java之反射

1.什么是反射?
必须是运行的状态下,都能够获取到这个类的所有的属性和方法。
对于类中的任意一个对象对象,都能够调用它的任意一个方法和属性。
这种动态获取的信息以及这种动态调用的对象的方法的功能就是java中反射


2.理解Class类?
Class 对象只能由系统建立对象
  –一个类在 JVM 中只会有一个Class实例
  –每个类的实例都会记得自己是由哪个 Class 实例所生成

3..该才能怎样执行反射机制?
就必须先要获取到该类的字节码文件对象(。class),
每一一个类对应着一个字节码文件也就对应着一个Class类型的对象,也就是字节码对象

3.获取字节码文件对象的三种方式
Class cla = Class.forName("包名+类名");//此时为源文件阶段,并没有改变字节码文件
Class cla1 = person.class;//获取自己,字节码阶段
Class cla2 = p.getClass();//创建对象的状态
有了字节码文件对象才能获得类中所有的信息

4.掌握 Constructor、Method、Field 类的用法
Constructor 

1).Field[] getFields():获取所有的"公有字段"
  2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
  2.获取单个的:
   1).public Field getField(String fieldName):获取某个"公有的"字段;
   2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
  
    设置字段的值:
   Field --> public void set(Object obj,Object value):
   参数说明:
  1.obj:要设置的字段所在的对象;
   2.value:要为字段设置的值;
 
 
 
 
new 和newInstance的区别:
从jvm的角度看,我们使用new的时候,这个要new的类可以没有加载; 
  但是使用newInstance时候,就必须保证:1、这个类已经加载;2、这个类已经连接了。而完成上面两个步骤的正是class的静态方法forName()方法,这个静态方法调用了启动类加载器(就是加载java API的那个加载器)。 
  有了上面jvm上的理解,那么我们可以这样说,newInstance实际上是把new这个方式分解为两步,即,首先调用class的加载方法加载某个类,然后实例化。 
  这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了我们降耦的手段。 


       newInstance: 弱类型。低效率。只能调用无参构造。 
       new: 强类型。相对高效。能调用任何public构造。


通俗来讲:


每创建完一个类就会生成一个独一的 (.class) 文件,创建之后jvm会自动分配到一块空间内存来存储,然后一个类只能产生一个class对象,只有通过拿到产生的唯一的class对象来实现java反射机制来获取类中的所有信息,共有私有都可以过去到;他就会变成一个透明的类

//获取字节码方式三种
        //第一种
        Student stu = new Student();
        Class class1 = stu.getClass();
        System.out.println(class1);
        
        //第二种
        Class class2 = Student.class;
        System.out.println(class2);
        
        //第三种
        Class class3 = Class.forName("cn.happy.reflect.Student");
        System.out.println(class3);
        
        
    
        
        System.out.println("获取公有的字段");
        Field[] getreflector = class3.getFields();
        for (Field field : getreflector) {
            System.out.println(field);
        }
        
        
        System.out.println("获取指定公有的字段");
        Field getreflector2 = class3.getField("name");
        System.out.println(getreflector2);
        
        System.out.println("获取所有的字段");
        getreflector = class3.getDeclaredFields();
        for (Field field : getreflector) {
            System.out.println(field);
        }
        
        //获取字段并赋值
        System.out.println("获取指定公有的字段并赋值");
        Field getreflector3 = class3.getField("name");
        System.out.println(getreflector3);
        
        Object obj = class3.newInstance();
        getreflector3.set(obj, "鬼鬼");
        Student stus = (Student)obj;
        stus.name="啦啦";
        System.out.println(getreflector3.get(stus));
        System.out.println("****************");
        System.out.println(stus.name);
    }
有了字节码文件对象才能获得类中所有的信息
通俗来讲:
有了字节码文件对象就可进行反射获取对象中的属性

总结
在反射机制概述中,我们了解到了java的一个动态特性:反射  知道了反射机制是一种动态获取信息以及动态调用对象方法的功能。
通过反射我们可以在运行时判断任意一个对象所属的类,在运行时构造任意一个类的对象,判断任意一个类所具有的方法和属性,同时,也可以在运行时调用任意一个对象的方法以及生成动态代理,如果编译时我们根本无法预知该对象或类可能属于哪些类,程序只能依靠运行时信息来发现该对象和类的真实信息,那么此时我们就必须使用反射。
事实上,在我们平时写代码的时候反射技术用的并不是很多,因为通过反射创建对象时性能要稍微低一些,只有当程序需要动态创建某个类的对象时才会使用反射Class类是反射的核心类。

 

 

posted @ 2018-08-02 12:17  南屿~  阅读(156)  评论(0编辑  收藏  举报