zoukankan      html  css  js  c++  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构造。
     
    代码示例:
    package cn.reflection;
    
    public class Person {
    
        public String name;
        char sex;
        private int health;
        protected int age;
    
    }
    package cn.reflection;
    
    import java.lang.reflect.Field;
    
    public class Reflect {
    public static void main(String[] args) throws Exception{
        
        //方式一获取字节码
        Person ePerson=new Person();
        Class class1=ePerson.getClass();
        System.out.println(class1);
        //方式二
        Class class2=Person.class;
        System.out.println(class2);
        //方式三  使用几率大
        Class class3=Class.forName("cn.reflection.Person");
        System.out.println(class3);
        System.out.println("-----------------华丽的分割线------------");
        System.out.println("获取公有字段!!");
        Field[] publicfield=class3.getFields();
        for (Field field : publicfield) {
            System.out.println(field);
        }
        System.out.println("-----------------华丽的分割线------------");
        System.out.println("获取所有字段!!");
        publicfield=class3.getDeclaredFields();
        for (Field field1 : publicfield) {
            System.out.println(field1);//   访问字段名.getName()
        }
        
        System.out.println("-----------------华丽的分割线------------");
        System.out.println("获取指定呆的公有字段并给他赋值!");
        
        Field pFields=class3.getField("name");
        System.out.println(pFields);
         //实例化一个object类
        Object object=class3.newInstance();
        pFields.set(object, "你好");         
        Person  person=(Person)object;
        System.out.println("hello"+pFields.get(person));
    }
    }
  • 相关阅读:
    20.GC日志详解及日志分析工具
    19.JVM调优工具锦囊
    两个页面的传参(转自博客园的春哥也编程)
    纯js实现背景图片切换
    关于引用类型用ref传参的问题
    C++ return
    C++内存管理
    Chrome插件开发一(配置文件)
    C++对象传递
    const 与 #define 的比较
  • 原文地址:https://www.cnblogs.com/caiguoxin/p/9339959.html
Copyright © 2011-2022 走看看