问题解决(Troubleshooting)

   下面例子列出了在反射类中可能会遇到的典型问题。

编译告警:“注意:…使用未受检异常或者不安全操作”

   当一个方法被调用,则它的参数值被校验并可能被转换。ClassWarning调用getMethod()来造成典型未受检版本告警:

import java.lang.reflect.Method;
public class ClassWarning{
    void m(){
        try{
            Class c = ClassWarning.class;
            Method m = c.getMethod("m");
        }catch(NoSuchMethodException x){
            x.printStackTrace();
        }
    }
}
$ javac ClassWarning.java
Note: ClassWarning.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
$ javac -Xlint:unchecked ClassWarning.java
ClassWarning.java:6: warning: [unchecked] unchecked call to getMethod
  (String,Class<?>...) as a member of the raw type Class
Method m = c.getMethod("m");  // warning
                      ^
1 warning

   许多库方法使用泛型声明来改进,包括Class中的方法。由于 c被声明为原型类(没有形参)并且 getMethod()是一个参数化类型,一个受检异常发生,编译器需要一个泛型告警。

   有两种方法可以解决,比较受欢迎的方法是添加合适的泛型来修改c的声明,在这个例子中,如:

Class<?> c = warn.getClass();

相反,使用注解@SuppressWarning处理这个问题时,告警会被隐藏。

Class c = ClassWarning.class
@SuppressWarnings("unchecked")
Method m = c.getMethod("m");

构造方法不可访问异常(InstantiationException when the Constructor is Not Accessible)

   Class.newInstance()将抛出一个InstantiationException异常,如果试图构建一个对象并且没有无参构造方法,类ClassTrouble例子阐述了结果栈信息:

class Cls{
    private Cls(){} 
}
public class ClassTrouble{
    public static void main(String ... args){
        try{
            Class<?> c = Class.forName("Cls");
            c.newInstance();
        }catch(InstantiationException x){
            x.printStackTrace();
        }catch(IllegalAccessException x){
            x.printStackTrace();
        }catch(ClassNotFoundException x){
            x.printStackTrace();
        }
    }
}
$ java ClassTrouble
java.lang.IllegalAccessException: Class ClassTrouble can not access a member of
  class Cls with modifiers "private"
        at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
        at java.lang.Class.newInstance0(Class.java:349)
        at java.lang.Class.newInstance(Class.java:308)
        at ClassTrouble.main(ClassTrouble.java:9)

   Class.newInstance()行为和new关键字非常相似,new方法也会因为同样的原因失败。在反射中,典型的解决方法是充分利用java.lnag.reflect.AccessibleObject类,它提供能够限制访问控制校验,然而,这种方式不能使用,因为java.lang.Class没有继承AccessibleObject,仅有的解决方法是将代码修改为Constructor.newInstance(),它不需要继承AccessibleObject.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值