高新技术之反射

来源:互联网 发布:手机淘宝卖家软件 编辑:程序博客网 时间:2024/05/22 07:47


反射:

反射就是把Java类中的各种成分映射成相应的java类。例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field、Method、Contructor、Package等等。
一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象后,得到这些实例对象后有什么用呢?怎么用呢?这正是学习和应用反射的要点。

综上所述:    反射就是把java类中的各种成分映射成为相应的java类


如何得到各个字节码对应的实例对象( Class类型)

     类名.class,例如,System.class
     对象.getClass(),例如,new Date().getClass()
     Class.forName("类名"),例如,Class.forName("java.util.Date");

 

Constructor类代表某个类中的一个构造方法

得到某个类所有的构造方法:
     Constructor [] constructors= Class.forName("java.lang.String").getConstructors();

得到某一个构造方法:
     //获得方法时要用到类型
     Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);

创建实例对象:
     通常方式:String str = new String(new StringBuffer("abc"));
     //注意转型
     反射方式: String str = (String)constructor.newInstance(new StringBuffer("abc"));

得到一个成员变量字节码对象
Field类代表某个类中的一个成员变量

     Person person = new Person(11, 12);
     Filed field = person.getClass().getField("x");

暴力反射,取得私有的成员变量
     Field field = person.getClass().getDeclaredField("y");
     //设置成员变量可访问
    
field.setAccessible(true);
     //取得值
     field.get(person);

 

得到一个类得方法
Method类代表某个类中的一个成员方法

     Method method = person.getClass().getMethod("setY",int.class );
     //调用方法
     method.invoke(person, 9);
     //null代表静态方法
     method.invoke(NUll,9);

 

JDK1.4和JDK1.5的invoke方法区别
       1.5(使用了可变参数) public Object invoke(Object obj,Object ...args);
       1.4(使用的是数组)public Object invoke(Object obj,Object[] args);

 

两种向invoke方法传数组的方式:

 因为:这个方法:有自动拆包功能
 所以:写成:
 method.invoke(person,new String[]{"1","2","3"});

 改为:
 method.invoke(person, (Object)new String[]{"1","1","2"});
 method.invoke(person, new Object[]{new String[]{"1","2","3"}});

 


得到数组的字节码对象
 int[] a1 = new int[3];
 int[] a2 = new int[4];
 //当数组类型相同,获得相同字节码
 System.out.println(a1.getClass()==a2.getClass());
 //class [I  [代表数组,I代表int类型
 System.out.println(a1.getClass());

Arrays.asList处理int[]和String[]的差异

 int[] a1 = new int[]{1,2,3};
 String[] a4 = new String[]{"a","b","c"};

 System.out.println(Arrays.asList(a1));打印出[[I@1bc4459]
 System.out.println(Arrays.asList(a4));打印出[a,b,c]

 jdk1.5:public static <T> List<T> asList(T... a);
 //int[]不能当做参数传入 asList,所以跳到jdk1.5里面执行
 jdk1.4:public static <T> List<T> asList(Object[] a);

 

数组的反射
 例:
 private static void printObject(Object obj){
  Class clazz = obj.getClass();
  if(clazz.isArray()){
   int len = Array.getLength(obj);
   for(int i=0;i<len;i++){
    //数组的反射,你是数组我就拆
    System.out.println(Array.get(obj,i));
   }
  }
  else{
   System.out.println(obj);
  }
 }

 注意,只能得到数组中的某个元素的类型,不能得到数组类型
 如:
 Object[] obj = new Object[]{"a",1};
 obj[0].getClass().getName();

 


使用配置文件来获取类的对象
 //取得这个文件的输入流
 InputStream ips = ReflectTest2.class.getClassLoader().getResourceAsStream("cn/itcast/day1/config.properties");
 //创建properties对象
 Properties props = new Properties();
 //加载数据
 props.load(ips);
 ips.close();
 String className = props.getProperty("className");
 //使用反射获得对象
 Collection collections = (Collection)Class.forName(className).newInstance();

 

框架与框架要解决的核心问题
我做房子卖给用户住,由用户自己安装门窗和空调,我做的房子就是框架,用户需要使用我的框架,把门窗插入进我提供的框架中。框架与工具类有区别,工具类被用户的类调用,而框架则是调用用户提供的类。
框架要解决的核心问题
我在写框架(房子)时,你这个用户可能还在上小学,还不会写程序呢?我写的框架程序怎样能调用到你以后写的类(门窗)呢?
因为在写才程序时无法知道要被调用的类名,所以,在程序中无法直接new 某个类的实例对象了,而要用反射方式来做