分享

Accessing non-visible classes with reflection

 小胡子的是也 2016-01-13

I am trying to get an instance of a non-visible class, AKA package private class, using reflection. I was wondering if there was a way to switch the modifiers to make it public and then access it using Class.forName. When I try that now it stops me saying I can't do it. Unfortunately there is no setAccesible method of the Class class.

asked Feb 22 '13 at 2:05
Josh Sobel
308520
    
setAccesible is defined on Constructor, Method or Field and not on Class. Use getConstructor API on class to get its constructor – Shiva Kumar Feb 22 '13 at 2:09
    
But where is the problem? Why you want to use reflection? Can't you just use new full.package.name.of.YourClass()? Are all constructors package/private? – Pshemo Feb 22 '13 at 2:11
    
no not if the class im using is in a different package – Josh Sobel Feb 22 '13 at 2:12
    
Why would you want to do this? That class is probably package private for a reason. – Louis Wasserman Feb 22 '13 at 2:59
up vote 17 down vote accepted

[for not nested classes]

I assume that constructors of that class are not public. In that case you can do it this way

Lets say you have class A in some package

package package1;

public class A {
    A(){
        System.out.println("this is default constructor");
    }
}

to create its object you can use its constructor like this

Class c = Class.forName("package1.A");//full package name
//note: getConstructor() can return only public constructors,
//you need to use 
Constructor constructor = c.getDeclaredConstructor();

constructor.setAccessible(true);
Object o = constructor.newInstance(null);

[for nested classes]

If you want to get Class of inner class with Class.forName you need to use this form

Class clazz = Class.forName("package1.Outer$Inner");

$ says that class after it is inner. Inner classes are very similar to methods, they have access to all members of its outer class, and to exists/work need instance of that outer class, so while creating instance of Inner class you have to pass reference to instance of Outer class.

Here is example.

package1

package package1;

public class Outer {
    class Inner{
        Inner(){
            System.out.println("default constructor of inner class");
        }
    }
}

package2

package package2;

import package1.Outer;
import java.lang.reflect.Constructor;

public class Test {
    public static void main(String[] args) throws Exception {

        Outer outerObject = new Outer();

        Class innerClazz = Class.forName("package1.Outer$Inner");

        // constructor of inner class as first argument need object of
        // Outer class
        Constructor constructor = innerClazz.getDeclaredConstructor(Outer.class);

        //we need to make constructor accessible 
        constructor.setAccessible(true);

        //now we need to pass instance of outer class in constructor
        Object o = constructor.newInstance(outerObject);

        System.out.println("we created object of class: "+o.getClass().getName());

    }
}
answered Feb 22 '13 at 2:28
Pshemo
61.7k765113
    
thanks i git it to work with constructor instead os Class.newInstance is it posssible to do with inner classes? – Josh Sobel Feb 22 '13 at 12:15
    
@JoshSobel check my edited answer – Pshemo Feb 22 '13 at 16:18

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多