代码:
public class ReflectTest {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException, NoSuchMethodException {
Class clz = Class.forName("A");
A a = (A) clz.getConstructor().newInstance();
System.out.println(a);
}
}
class A{
private String name = "asd";
A(){
}
}
报错:
Exception in thread "main" java.lang.NoSuchMethodException: A.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getConstructor(Class.java:1825)
at ReflectTest.main(ReflectTest.java:6)
解决方案1:
将构造方法加上public
public class ReflectTest {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException, NoSuchMethodException {
Class clz = Class.forName("A");
A a = (A) clz.getConstructor().newInstance();
System.out.println(a);
}
}
class A{
private String name = "asd";
public A(){
}
}
解决方案2:
类A使用public分别进行修饰,ReflectTest和A类分别放在不同的java文件,都使用public进行修饰。
public class ReflectTest {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException, NoSuchMethodException {
Class clz = Class.forName("A");
A a = (A) clz.getConstructor().newInstance();
System.out.println(a);
}
}
public class A{
private String name = "asd";
A(){
}
}
原因分析:
这里就看源码进行分析了
首先查看报出异常的地方。是Class的 getConstructor() 方法。那就看源码是怎么说。
@CallerSensitive
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return getConstructor0(parameterTypes, Member.PUBLIC);
}
打了断点之后,发现是在return的时候抛出的异常。那么继续看 getConstructor0() 的源码。
private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
int which) throws NoSuchMethodException
{
Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
for (Constructor<T> constructor : constructors) {
if (arrayContentsEq(parameterTypes,
constructor.getParameterTypes())) {
return getReflectionFactory().copyConstructor(constructor);
}
}
throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
}
继续打断点,找到是在Constructor<T>[] constructors没有获取到PUBLIC的方法。那么就可以知道是因为没在构造方法前没有加public。
构造方法不都是默认为public的吗?为什么第二种解决方法可以解决呢?
这里就有一个非常的细节了!!
构造方法的访问权限是根据类的访问权限而进行修饰的!!!!!
也可以查看class文件可知:
没有使用public修饰class
使用public修饰类的class