神奇的java反射机制

最近在开发一个小型的j2ee项目,沿用以前公司成熟的struts + spring + hibernate三层架构,只是做些修改,加一些新的业务规则进去(这也让我这个新手体验到了面向对象的可重用性的优点),在开发的过程中我无意中发现以前公司的项目中spring托管的中间层的类里面都用的是private的默认构造方法,我感到奇怪,难道具有私有的构造方法的类也能new一个对象出来?我立马在msn上请教了我的师傅--公司的前辈,回答说是用java的反射机制,于是我上网搜索了有关java反射的资料,对java的反射机制也有了些了解,但是这些毕竟都是别人说的,我自己还需亲自验证一下,于是有了下面的代码:

java 代码
  1. package com.ref;   
  2.   
  3. public class A {   
  4.     private A() {   
  5.         System.out.println("This is a private Constructor");           
  6.     }   
  7.     /**  
  8.     private A(String str, int i) {  
  9.         System.out.println("str = " + str);  
  10.         System.out.println("i = " + i);  
  11.     }  
  12.     */  
  13. }  
java 代码
  1. package com.ref;   
  2.   
  3. import java.lang.reflect.Method;   
  4. import java.lang.reflect.Constructor;   
  5.   
  6. public class TestReflect {     
  7.     public static void main(String args[]) throws Exception {   
  8.         //产生class   
  9.         Class a = Class.forName("com.ref.A");          
  10.            
  11.         //返回 Constructor 对象的一个数组,这些对象反映此 Class    
  12.         //对象表示的类声明的所有构造方法。它们是公共、保护、默认   
  13.         //(包)访问和私有构造方法。返回数组中的元素没有排序,   
  14.         //也没有任何特定的顺序。如果该类存在一个默认构造方法,   
  15.         //则它包含在返回的数组中。如果此 Class 对象表示一个接口、   
  16.         //一个基本类型、一个数组类或 void,则此方法返回一个长度为 0 的数组。   
  17.         Constructor [] constructs = a.getDeclaredConstructors();   
  18.         for(int i = 0; i < constructs.length; i++) {   
  19.             System.out.println(constructs[i].getName());   
  20.                
  21.             //将Constructor对象的 accessible 标志设置为true   
  22.             constructs[i].setAccessible(true);   
  23.             constructs[i].newInstance(null);   
  24.         }   
  25.   
  26.     }   
  27. }  

该程序运行后在控制台打印如下信息:

         com.ref.A
         This is a private Constructor

事实胜于雄辩,看来java的反射机制确实能new出一个带有private构造方法的对象来,类似的,像getDeclaredMethods() 和getDeclaredFields()都可以得到private的元素。这个也说明了单例模式在语法角度是不能保证的。完全可以调用private的构造方法生成一个对象。访问级别(access level)仅仅是编译期检查的项目,在运行期没有限制作用。

我没有看过spring框架的源码,但我估计spring就是靠java 的反射机制来得到对象的,现在我们不妨来玩一玩,我们来把上面第一段代码中关于A.java的另一个带有参数的私有构造方法前面的注释去掉,编译运行,这时候控制台抛出了异常:

         Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments

那我们再来看看spring在这个问题上是不是够健壮,考验下spring的动态反射到底有多强大,到底是不是“nothing is impossible”,我把正在做的那个项目的中间层的代码稍微做了修改,把spring托管的类的私有默认构造方法加了一个参数,然后保存,编译,并重起了tomcat服务器,察看后台日志stdout.log,发现抛了异常:

        org.springframework.beans.FatalBeanException: Could not instantiate class [com.ss.watch.serv.SysService]: no default constructor found;

看来spring虽然反射运用的出神入化,但是还是有其局限性的啊,有待后续版本进一步完善,呵呵

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值