相信大家在日常开发中,都有用到过Class.newInstance()方法,如果有人没有接触过,也没关系,我会给大家介绍下这个方法的使用方式。
① 方法使用介绍:
该方法属于静态方法,调用方式Class.newInstance(),返回的是Class对象所对应的类的实例,用于在知道Class对象情况下,创建实例对象。
② 方法异常介绍:
IllegalAccessException:如果该类或其空(null)构造方法是不可访问时,会抛出该异常;
InstantiationException:如果此 Class 表示一个抽象类、接口、数组类、基本类型、void 、该类没有 null 构造方法或者由于其他某种原因导致实例化失败时,会抛出该异常;
ExceptionInInitializerError:如果初始化失败,会抛出该异常;
SecurityException:如果存在一个安全管理器s,并且调用方的类加载器与当前类的类加载器不相同或不是子父类的关系,校验包访问 link SecurityManager#checkPackageAccess s.checkPackageAccess() 拒绝访问该类的包时,抛出该异常。
相信大家此时都会使用该方法,也知道该方法异常代表的含义,接下来就进入本篇博文的中心内容,很简单听我慢慢将来。
在大家使用注解并通过Class.newInstance() 进行类对象创建的时候,相信大家都被注解的魅力所感染,每个项目在发布之前,大家都会做一件事,那就是混淆,提高代码的抗风险能力,在我们混淆的过程中,就会出现Class.newInstance() 方法调用抛出InstantiationException异常,这时候相信大家都会很困扰,我们在没有混淆的状态下,没有异常产生,只要开启混淆就有这个异常,此处莫慌,经过我上面对Class.newInstance()方法的介绍,相信大家都知道了这个异常产生的诱因,但是大家会问,我的代码都很好的避开了,这个异常产生的条件,我的代码没问题啊!!!
我当时也是这么想的,我的代码没问题,那么此时大家就排除了代码逻辑调用问题,那么问题,出现在哪里呢?我在网上查阅很多资料,出现这个异常都是因为,调用出的问题,导致在未混淆的状态下,就出现异常,都和我的不一样!
我只能冷静的坐下来,分析问题的本质,从根源入手,通过查看Class.newInstance() 源码,发现它是通过Class对象去创建对应的实例,代码混淆会导致类全路径的改变,通过以前对Class.forName(String className)这个方法的使用与启发,我通过代码获取了我要创建的类的全路径,发现类的全路径出现了abc这样的单字符的描述,如果调用Class.forName(String className)去创建该类的Class对象就会出现问题,因为程序不认识这个类的全路径,没办法找到对应类,自然也就创建不了Class对象,同理我们在调用Class.newInstance()这个native方法时,也是要保证让程序先找到这个Class对象,再去创建该Class对象对应的实例,所以解决方案自然就有了,只需要保证我们这个Class对象要创建的实例所在类的全路径正确即可,也就是不要混淆该类的全路径,通过-keep进行设置。
本篇博文到这里就结束了,感谢大家不厌其烦的看我的问题讲述,希望对大家有帮助,多多支持!!!