• 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类是反射的核心类。

     

  • 相关阅读:
    JAVA向上转型和向下转型
    LeetCode记录之9——Palindrome Number
    LeetCode记录之7——Reverse Integer
    JAVA数据结构--插入排序
    JAVA数据结构--选择排序
    JAVA数据结构--冒泡排序
    HTTP协议04-返回状态码
    HTTP协议03-http特点及请求方式
    HTTP协议02-请求和响应的报文构成
    HTTP笔记01-http相关的基础知识
  • 原文地址:https://www.cnblogs.com/hsa521/p/9406419.html
Copyright © 2020-2023  润新知