Java: Subpackage visibility?

2019-01-10 22:07发布

I have two packages in my project: odp.proj and odp.proj.test. There are certain methods that I want to be visible only to the classes in these two packages. How can I do this?

EDIT: If there is no concept of a subpackage in Java, is there any way around this? I have certain methods that I want to be available only to testers and other members of that package. Should I just throw everything into the same package? Use extensive reflection?

8条回答
▲ chillily
2楼-- · 2019-01-10 22:29

You can't. In Java there is no concept of a subpackage, so odp.proj and odp.proj.test are completely separate packages.

查看更多
祖国的老花朵
3楼-- · 2019-01-10 22:32

As others have explained, there is no such thing as a "subpackage" in Java: all packages are isolated and inherit nothing from their parents.

An easy way to access protected class members from another package is to extend the class and override the members.

For instance, to access ClassInA in package a.b:

package a;

public class ClassInA{
    private final String data;

    public ClassInA(String data){ this.data = data; }

    public String getData(){ return data; }

    protected byte[] getDataAsBytes(){ return data.getBytes(); }

    protected char[] getDataAsChars(){ return data.toCharArray(); }
}

make a class in that package that overrides the methods you need in ClassInA:

package a.b;

import a.ClassInA;

public class ClassInAInB extends ClassInA{
    ClassInAInB(String data){ super(data); }

    @Override
    protected byte[] getDataAsBytes(){ return super.getDataAsBytes(); }
}

That lets you use the overriding class in place of the class in the other package:

package a.b;

import java.util.Arrays;

import a.ClassInA;

public class Driver{
    public static void main(String[] args){
        ClassInA classInA = new ClassInA("string");
        System.out.println(classInA.getData());
        // Will fail: getDataAsBytes() has protected access in a.ClassInA
        System.out.println(Arrays.toString(classInA.getDataAsBytes()));

        ClassInAInB classInAInB = new ClassInAInB("string");
        System.out.println(classInAInB.getData());
        // Works: getDataAsBytes() is now accessible
        System.out.println(Arrays.toString(classInAInB.getDataAsBytes()));
    }
}

Note that this only works for protected members, which are visible to extending classes, and not package-private members, which aren't. Hopefully this helps someone!

查看更多
登录 后发表回答