首页 > 代码库 > 黑马程序员——Java高新技术——反射的复写

黑马程序员——Java高新技术——反射的复写

由于第一段视频学习效果不理想,希望重新看一遍反射视频,并多方面寻找资料,重新写一遍总结,以期java能力早日提高。

Java——反射

一、Class类

  Class 类的实例表示正在运行的 Java 应用程序中的类和接口。所以,Class可以提供方法获得动态的java类中的各个属性;

(由定义可以知道Class创建的思路就是获得某一个特定java类的信息然后传给Class的对象,那么具体怎么做呢?)

这里说得java类的信息指的就是该java类的计算机的字节码:传给 Class cls1:

所以有三种方向得到

1.从类名得到:类名.class;

2.从具体的对象得到:Person p1=new Person();那么字节码:p1.getClass();

3.Class类它自身的静态方法,能指定得到某个类的字节码:Class.forName("java.Lang.String");

做反射的时候一般用第三种:因为写原程序的时候,我的类可能还没过创建;

注:八种数据类型和void,预定义的类名,直接类名.class就能创建Class。

 1 String strl="abc"; 2         Class cls1=String.class; 3         Class cls2=strl.getClass(); 4         Class cls3=Class.forName("java.lang.String");//最后这钟有ClassNotFoundException 5 //        判断三者是否相同,因为多少取同一个类的字节码当然相同啦 6         System.out.println(cls1==cls2); 7         System.out.println(cls1==cls3); 8          9 //        Class.isPrimitive()方法是判断是否是基本数据类型对应的Class10         System.out.println(cls1.isPrimitive());//肯定是false11         System.out.println(int.class.isPrimitive());//肯定是true12         System.out.println(int.class==Integer.class);//Integer是类啊,大哥13         System.out.println(int.class==Integer.TYPE);//不过这些保证类提供了一个方法.TYPE返回指定类型14         System.out.println(int[].class.isPrimitive());//数组当然不是啦15         System.out.println(int[].class.isArray());//但是Class.isArray可以判断是否数组

 

二、反射定义与意义:

  反射就是把Java类中的各个成分映射成相应的Java类中(即是Class类),这个Class类提供一系列的方法,来获取其中的变量、方法、构造方法

修饰符、包等信息,这些信息用相应的实例对象来表示,他们就是Field、Method、Contructor、Package等;

 

  既然一个类中的每个成员都能使用反射的方式来表示,那么怎么得到这些Class类的实例对象,这些实例对象怎么用,用在哪里,就是反射的要点:

 

三、Constructor(获得构造方法的类)

(1)获得途径:Class类中提供了一个方法:getConstructors()(注意:有s,代表获得这个Class类中所以的构造方法)

  例如:Constructor[] constructor=Class.forName("java.lang.String").getConstructors;

        getConstructor(参数)得到某个参数对应的特点的构造方法:

  例如:

(2)可以调用Class类中getConstructor(String.class,int.class)方法获取指定的构造函数,

    在使用newInstance(”zahns“,23)来获取具体的对象;

1 //        关于Constructor类,关于new String(new StirngBuilffer("abc"))2         Constructor constructor1=String.class.getConstructor(StringBuffer.class);//得到这个特定参数对应的构造方法3         String str=4             (String) constructor1.newInstance(new StringBuffer("abc"));5         //和new String(new StirngBuilffer("abc"))一个意思了,注意强转6         System.out.println(str.charAt(2));//答案是c

(我的理解:getConstructor和newInstance这连个步骤分别可以说是声明传入特定类型的,然后就是具体传入什么类型的)

(3)Class.newInstance()方法:

  String obj=(String)Class.forName("java..lang.String").newsInstance();

   该方法内部先得到默认的构造方法,然后用构造方法创建对象;

     Class类中的newinstance()方法是使用无参的构造函数创建对象,如果一个类没有参的构造函数,就不能这样创建了。

 

四、Field类(字段,变量) 

  *CLass.getFidle("变量名")方法可以获得类中指定的字段,然后用Field中get(类名对象)获得实际值;

  *而如果字段是私有的时候使用暴力反射,用人getDeclaredField("变量名")获取,通过get(obj,"")

ReflecPoint 是自定义的类,x私有,y公用

1     ReflecPoint pt1=new ReflecPoint(3,5);2         Field fielY=pt1.getClass().getField("y");3 //        这样依然不能获得y的值4         System.out.println(fielY.get(pt1));//为55 //            那么私有的需要使用暴力反射6         Field fielX=pt1.getClass().getDeclaredField("x");7         fielX.setAccessible(true);//这部是必须的8         System.out.println(fielX.get(pt1));//为3
 1 public class ReflecPoint { 2     private int x; 3     public int y; 4      5     String pp1="asfsdfsdg"; 6     String pp2="asfsasddg"; 7     String pp3="asfsdfaddg"; 8     public ReflecPoint(int x, int y) { 9 //        super();默认的10         this.x = x;11         this.y = y;12     }13     public String toString(){14         return pp1+":"+pp2+":"+pp3;15     }16 }
 1         ReflecPoint pt1=new ReflecPoint(3,5); 2         changeStringValue(pt1); 3         System.out.println(pt1); 4     } 5 //将变量中的String中的b改成a 6     private static void changeStringValue(Object obj) throws Exception { 7         Field[] fields=obj.getClass().getFields(); 8         for(Field field : fields){ 9             if(field.getType()==String.class){//比较的是字节码是否相同10                 String old=(String)field.get(obj);11                 String news=old.replace(b, a);12                 field.set(obj, news);13             }14     }

 

五、Method类

 

黑马程序员——Java高新技术——反射的复写