首先贴出错误的日志:
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里为什么会大量的使用构造方法来创建类了。
所以我觉得使用这种方式更加的稳妥。