java反射踩坑

代码:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值