黑马程序员-java之反射

------------android培训java培训、-----------


1 如何得到字节码对应的实例对象(Class类型)
  方式一:类名.class 例如:System.class    
  方式二:getClass() 例如:new Date().getClass()
  方式三:Class.forName("类名") 例如:Class.forName("java.util.Date");注意:这里的类名要用全名
2 9个预定义的Class实例对象
  boolean.class,byte.class,short.class,int.class,long.class,float.class,double.class,char.class,void.class
  int.class==Integer.TYPE
3 数组类型的Class实例对象
  Class.isArray()
  只要是在源程序中出现的类型,都有各自的Class实例对象,例如int[],void
4 反射就是把Java类中的各种成分映射成相应的java类(Method,Field,Constructor,Package等等)
  System.exit()-->Methodobj1
  System.getProperty()-->Methodobj2
5 得到某个类所有的构造方法
  Constructor[] cons = Class.forName("java.lang.String").getConstructors();
6 得到某一个构造方法
  Constructor con = Class.forName("java.lang.String").getConstructor(StringBuffer.class);//表示得到构造方法String(StringBuffer sb)注意:由于反射加载都很消耗内存,所以一般把反射后生成的常用的构造方法之类存储成变量形式,提高效率,这就是优化
  (String)con.newInstance(new StringBuffer("abc"));//相当于new String(new StringBuffer("abc"));
  Class.forName("java.lang.String").newInstance();//相当于 new String();
7 成员变量反射
  ReflectPoint pt1 = new ReflectPoint(3,5);
  Field fieldY = pt1.getClass().getField("y");//fieldY不是对象身上的变量,而是类上的成员变量,所以必须对应到具体的某个对象上的成员变量值;getField()只能对public修饰的成员变量进行访问
  System.out.println(fieldY.get(pt1));
  Field fieldX = pt1.getClass().getDeclaredField("x");//getDeclaredField()可以对声明过的任何成员变量访问
  fieldX.setAccesible(true);//强制获取变量值
  System.out.println(fieldX.get(pt1));
8 利用反射改变对象中原成员变量的值
  changeStringValue(Object obj){
    Field[] fields = obj.getClass().getFields();//获得对象对应的类中所有的成员变量
    for(Field field : fields){//遍历成员变量数组
           if(field.getType()==String.class){//因为String类在内存中就一份字节码文件所以这里用==
            String oldValue = (Sring)field.get(obj);//获得对象中字符串成员变量的值
            String newValue = oldValue.replace('b','a');//将字符串成员变量值中的b字符替换成a字符
            field.set(obj,newValue); //改变对象中字符串变量的值
        }
    }
  }
9 利用反射调用具体某个方法
  Method methodCharAt = String.class.getmethod("charAt",int.class);//第一个参数表示方法名,第二个参数表示方法中参数的类型字节码,方法中有几个参数就写几个对应的类型字节码
  System.out.println(methodCharAt.invoke(str,1));//相当于str.charAt(1);
  注意:invoke()中的第一个参数如果为null,则表示该被调用的方法是静态方法static,不需要指明哪个对象调用
10 调用main()
  String startingClassName = args[0];
  Method methodMain = Class.forName(startingClassName).getmethod("main",String[].class);
  methodMain.invoke(null,new Object[]{new String[]{"123","456","789"}});//等同于methodMain.invoke(null,(Object)new String[]{"123","456","789"});
11 数组在内存中的字节码
  两个数组只有在元素类型相同,且数组维度相同的情况下,他们在内存中的字节码才是同一份字节码
  int[] a1 = new int[3];
  int[] a2 = new int[4];
  int[][] a3 = new int[2][3];
  String[] a4 = new String[3];
  System.out.println(a1.getClass() == a2.getClass());//true  
  System.out.println(a1.getClass() == a3.getClass());//false 维度不同
  System.out.println(a1.getClass() == a4.getClass());//false 元素类型不同
  Arrays.asList(Object[]) //如果参数是int[]则把整体作为一个Object对象,如果是String[]则把它看作是Object[],如果是int[][]则同样看成Object[]因为会把其中的一位数组int[]看作是一个Object对象
12 数组的反射应用
   void printObject(Object obj){
    Class clazz = obj.getClass();
    if(clazz.isArray()){
        int len = Array.getLength();
        for(int i = 0;i<len;i++){
            System.out.println(Array.get(obj,i));
        }
    }else{
        System.out.println(obj);
    }
   }
13java中的内存泄露
  Collection coll = new HashSet();
  ReflectPoint pt1 = new ReflectPoint(1,2);//提示:ReflectPoint类中的hashCode()是用成员变量x,y进行计算的,覆写了系统的哈希码算法
  ReflectPoint pt2 = new ReflectPoint(3,4);
  ReflectPoint pt3 = new ReflectPoint(1,2);

  coll.add(pt1);
  coll.add(pt2);
  coll.add(pt3);
  coll.add(pt1);

  pt1.y = 7;
  coll.remove(pt1);//由于pt1的y值已经发生改变,所以其哈希码也会发生变化,对应的哈希值区域就会改变,而删除的时候会去原来哈希值所在区域查找,所以会删除失败,导致内存无端被占用,内存泄露
  System.out.println(coll.size());//打印结果是2
14 反射的作用-->>实现框架功能(自己写的程序调用未知的类)
   假设配置文件是config.properties这样写的className=java.util.ArrayList
   InputStream ips = new FileInputStream("config.properties");
   Properties props = new Properties();
   props.load(ips);
   ips.close();
   String className = props.getProperty(className);
   Collection coll = (Collection)Class.forName(className).newInstance();
   
   ReflectPoint pt1 = new ReflectPoint(1,2);//提示:ReflectPoint类中的hashCode()是用成员变量x,y进行计算的,覆写了系统的哈希码算法
   ReflectPoint pt2 = new ReflectPoint(3,4);
   ReflectPoint pt3 = new ReflectPoint(1,2);

   coll.add(pt1);
   coll.add(pt2);
   coll.add(pt3);
   coll.add(pt1);   
 
   System.out.println(coll.size());//打印结果是4

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值