How to Access package private Class from a Class in some other package?

前提是你 提交于 2019-11-28 18:59:43

Is there any other way to do this ? Using reflection perhaps ?

Yes. Reflection can be used to bypass the Java access rules, if your application has full privilege.

For instance, to access a private field of an object from a different class, you need to:

  • Get the object's Class object.
  • Use the Class.getDeclaredField(...) method to get a Field object for the field.
  • Call Field.setAccessible(true) to turn off the access check.
  • Call Class.getField(object, Field) to get the field's value (or boxed value if it is a primitive type).

If the class itself is not accessible, you need to make sure that you don't refer to the classes identifier in your source code ... 'cos that will result in a compilation error. Instead, assign its reference to (say) variable of type Object or of some other visible supertype, and perform more specific operations on the instance reflectively.


As you might imagine, this is tedious and error prone. You'd be advised to find a better way, like:

  • getting the suppliers of the classes to fix whatever is causing you to need to break the visibility restrictions,
  • getting the suppliers of the classes to change their visibility,
  • finding another way to use the classes that doesn't require breaking open their abstraction, or
  • ditching them and finding (or writing) something better.

(Generally speaking, if you have to break open an abstraction then something is wrong with either the abstraction itself or the way you are using it.)


Finally, I should add that untrusted code is (should be) run in a security sandbox that blocks the use of the key reflective operations.

Following method Invokes default scoped class method using reflection

public void discardMap() {
    //CustomMap map = (CustomMap) hi.getMap();
    //map.discard();
    try {
        Object o =hi.getClass().getMethod("getMap").invoke(hi);
        Method m = o.getClass().getMethod("discard");
        m.setAccessible(true);
        m.invoke(o);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
Chandra Sekhar

It may not be possible because:

Class :

Accessible to class from same package?

  • public : yes
  • protected : yes
  • default : yes
  • private : no

Accessible to class from different package?

  • public : yes
  • protected : no
  • default : unless it is a subclass
  • private : no

I don't recommend to use non-API classes as they might change in any future version and can break your code.

How did you find out about this class? Is it an Open Source library?

Try to contact the authors of the library, tell them your use case and find a way with them to offer a public API. If it's an open source library you could help them by providing a patch.

Adding this solution for sake of completeness.

One option that I know is to move speak.hello.Hello to speak.hi.Hello as Now Hello is in package speak.hi it can access package private Class Hi

package speak.hi;

public class Hello {

    private Hi hi;

    Hello(Hi hi) {
        this.hi = hi;
    }

    public String sayHello() {
        return "Hello";
    }

    public String sayHi() {
        return hi.sayHi();
    }

    public static void main(String[] args) {
        Hello hello = new Hello(new Hi());
        System.out.println(hello.sayHello());
        System.out.println(hello.sayHi());
    }

}

Not possible. The security model is this : a model to provide security :) If you designed class Hi and delivered it to customers with private access, you wouldn't like them to be able to bypass your restrictions, would you?

I would think that if the authors of a library did not make a particular class part of the public API, it is because they don't want other people using it. You should respect the decision even though you can break it using reflection. Using private API is simply bad programming.

1st class is in package a.b.c.class1 but class1 is private as well as abstract 2nd class is in package a.b.c.class2 extends class1 but class2 is public

3rd class is in package x.y.z.class3

So as to access class1 in class 3 you can write something like:-

Class baseClass = (new class2()).getClass(); and use the instance of its superclass then use:- baseClass.getSuperClass(); and use it wherever you want.

But then again the baseclass was made abstract and private for a reason hence not advisable to do so but then again this solution could be used as a workaround.

Not Possible you can not create your Hi class as private.

I think by default the class will be "default" (package private, you can say), NOT "private". So it can be accessed with in the same package.

Moreover, you CANNOT make any *top level class Private in Java.

And if you want make a class default and still be able to access it in other package then what will be the purpose of having access specifiers (modifiers) ??

you either need to make class public or move to the same package.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!