黑马程序员技术交流社区

标题: 反射总结(我个人的完整版) [打印本页]

作者: mandoooo    时间: 2015-11-28 14:43
标题: 反射总结(我个人的完整版)
Class类:各个Java类属于同一类事物,描述这类事物的Java类名就是Class类。
Class.forName()作用:(1)如果已经在内存的话,不用再加载,直接返回字节码
                           (2)虚拟机里没有的话,用类加载器加载,返回给字节码
字节码对应的实例对象:(1)类名.class
                           (2)对象.getClass()
                           (3)Class.forName("类名");  运行的时候可以临时放进来。
字节码:当源程序中用到类时,首先要从硬盘把这个类的那些二进制代码,一个类编译成class放在硬盘上以后,就是一些二进制代码,要把这些二进制代码加载到内存中里面来,再用这些字节码去复制出一个一个对象来。
基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。

Boolean isPrimitive():判定指定的Class对象是否表示一个基本类型
Boolean isArray():判定此Class对象是否表示一个数组
getSuperClass():返回的父类
Constructor类
代表某个类的一个构造方法
(A)得到某个类所有的构造方法
   Constructor[] con=Class.forName(“Java.lang.String”).getConstructor();
(B)得到某一个构造方法:
   Constructor con=Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
(C)例:String str=new String(new StringBuffer("abc"));
    用反射:Constructor con=String.class.getConstructor(StringBuffer.class);//选择哪个构造方法
            String str=(String)con.newInstance(new StringBuffer("abc"));//传StringBuffer值
编译的时候他只知道是构造方法,不知道哪个类身上的构造方法。
运行的时候才知道对应的是哪个构造方法。
Field类
Class ReflectPiont
{
         public int y;
         private int x;
         ReflectPoint(int y,int x){
         This.y=y;
                   This.x=x;
}
}
Class FieldDemo
{
         public static void main(String[] args){
         ReflectPoint rp=new ReflectPoint(3,5);
         Field y=rp.getClass().getField(“y”);
//到这儿,y指的不是具体对象的变量值,而是ReflectPoint里的变量
         System.out.println(y.get(rp));
//所以get里要传递我指向的是哪一个对象,这时才会明确值
         Field x=rp.getClass().getDeclaredField(“x”)
                   x.setAccessible(true);  
//暴力反射
                   System.out.println(x.get(rp));
}
}
Method类:
代表某一个类中一个成员方法
(A)得到类中的某一个方法
      Method m=Class.forName(“Java.lang.String”).getMethod(“charAt”,int.class);
(B)通常方法:System.out.println(str.charAt(1));
      反射方法:Method m=str.getClass().getMethod(“charAt”,int.class);
                   m.invoke(str,1);
//如果传递给Method对象的Invoke()方法的第一个参数为null,说明该Method对象对应的是一个静态方法。
jdk1.4和jdk1.5的invoke方法的区别:
jdk1.5:public Object invoke(Object obj,Object...args)
jdk1.4:public Object invoke(Object obj,Object[] args)

数组的反射
基本类型的一位数组可以被当作Object类型使用,不能当作Object[]类型使用;非基本类型的一维数组,既可以当做Object类型使用,又可以当作Object[]类型使用。
Arrays.asList():处理int[]和String[]时的差异。
Array工具类用于完成对数组的反射操作。
怎么得到数组中的元素类型?
        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[] a=new Object[]{"a",1};
a[0].getClass().getName();
----------
反射的作用-〉实现框架功能
框架与框架要解决的核心问题
写程序时无法知道要被调用的类名,所以,在程序中无法直接New某个类的实例对象,用反射方法来做。

import java.io.FileInputStream;
import java.util.Collection;
import java.util.Properties;

public class ReflectTest {
        public static void main(String[] args) throws Exception
        {
                //InputStream fs=new FileInputStream("config.properties");
                //InputStream fs=ReflectTest.class.getClassLoader().getResourceAsStream("config.properties");
                InputStream fs=ReflectTest.class.getResourceAsStream("resources/config.properties");       
                Properties props=new Properties();
                props.load(fs);
                String className=(String)props.getProperty("className");
               
                fs.close();
               
                Collection collections=(Collection)Class.forName(className).newInstance();
                //Collection collections=new HashSet();
                ReflectPoint rp1=new ReflectPoint(3,3);
                ReflectPoint rp2=new ReflectPoint(4,3);
                ReflectPoint rp3=new ReflectPoint(3,3);
               
                collections.add(rp1);
                collections.add(rp2);
                collections.add(rp3);
                collections.add(rp1);
               
                System.out.println(collections.size());
        }
}
InputStream getResourceAsStream(String name):返回读取指定资源的输入流

JavaBean
JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
值对象:要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通向称之为值对象.
Beanutils工具包
在eclipse里,引入Beanutils工具包,等程序运行出错后再引入logging包

在前面内省例子的基础上,用Beanutils类先get原来设置好的属性,在将其set为一个新值。
   -get属性时返回的结果为字符串,set属性时可以接受任意类型的对象,通常使用字符串。

用PropertyUtils类先get原来设置好的属性,再将其set为一个新值。
   -get属性时返回的结果为该属性本来的类型,set属性时只接受该属性本来的类型。






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2