反射创建实例出现的问题

首先贴出错误的日志:
Exception in thread “main” java.lang.IllegalAccessException: Class test.test4 can not access a member of class 笔试.ListNode with modifiers “public”
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.Class.newInstance(Class.java:436)

具体的代入如下:

public class Solution implements Serializable {
	....
	//不重要的信息
	.....
}
class TreeNode {
    public   static int k = 10;
    public int val;
    static {
        System.out.println(k);
        System.out.println("我进入初始化阶段了TreeNode");
    }
  public TreeNode left;
    public TreeNode right;
    public TreeNode(){}
    public TreeNode(int x) { val = x; }
}
class ListNode {
    public  static int m = 10;
    public int val;
    public  ListNode next = null;
    static {
        System.out.println("我进入初始化阶段了ListNode");
    }
    public ListNode(){}
    public ListNode(int val) {
       this.val = val;
    }
}

上面的是需要被反射的类:

public class test4 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class<?> aClass3 = Class.forName("笔试.TreeNode");
        //这里无论如何改动都会出现问题,但是如果调用的是自己这个文件中的相同空的
        //类名的类,就不会出现问题,即使构造方法不是public的。
        //Class<?> aClass3 = Class.forName("test.TreeNode");
        aClass3.newInstance();
       // Constructor<?> constructor = aClass3.getConstructor(new Class[]{});
        //constructor.setAccessible(true);
        //Object o1 = constructor.newInstance(new Class[]{});
    }
}
class test_reflect{
    private static  int k = 0;
    test_reflect t = null;
    public test_reflect(){}
    public test_reflect(int i){}
}
class ListNode {
    private  static int m = 10;
    int val;
    ListNode next = null;
    static {
        System.out.println("我进入初始化阶段了ListNode");
    }
    public ListNode(){}
    public  ListNode(int val) {
        this.val = val;
    }
}

具体的原因不知道如何,只是知道如果直接这样调用会出现问题。
具体的解决方案就是不要直接的使用class.newinstance()的方法来创建,推荐使用constructor.newInstance(…)的方法来创建,在创建之前设置constructor的访问为true就可以了。
具体的代码如下:

public class test4 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class<?> aClass = Class.forName("笔试.ListNode");
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        Class<?> aClass1 = systemClassLoader.loadClass("笔试.TreeNode");
        System.out.println("开始反射获取field");
        Field m = aClass.getDeclaredField("m");
        Field k = aClass1.getDeclaredField("k");
        System.out.println("设置权限");
        m.setAccessible(true);
        k.setAccessible(true);
        System.out.println("通过field获取具体的值");
        System.out.println(m.get(null));
        System.out.println(m.get(null));
        System.out.println("开始创建实例");
//        Object o = aClass.newInstance();
//        Object o1 = aClass1.newInstance();

        Class<?> aClass2 = Class.forName("笔试.Solution");
        Object o = aClass2.newInstance();
        Class<?> aClass3 = Class.forName("笔试.ListNode");
        //获取具体的无参的构造方法
        Constructor<?> constructor = aClass3.getConstructor(new Class[]{});
        //设置权限
        constructor.setAccessible(true);
       	//开始创建
        Object o1 = constructor.newInstance(new Class[]{});
    }
}
class test_reflect{
    private static  int k = 0;
    test_reflect t = null;
    public test_reflect(){}
    public test_reflect(int i){}
}
class ListNode {
    private  static int m = 10;
    int val;
    ListNode next = null;
    static {
        System.out.println("我进入初始化阶段了ListNode");
    }
     ListNode(){}
      ListNode(int val) {
        this.val = val;
    }
}

我发现如果不是在同一个文件夹下的话,使用class.forname去获取不是public修饰的class类是会出现这样的错误。如:
在这里插入图片描述
解决方法就是上面的问题。
通过这个也算是有一点点的理解了Spring里为什么会大量的使用构造方法来创建类了。
所以我觉得使用这种方式更加的稳妥。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值