JAVA反射是什么呢?

1、一个类,相当于一个对象的“模子”,这个“模子”也占内存,故也能用变量来“引用”(引用:即,变量名--内存起址对应表)

2、类的加载:当程序要使用某个类时,如果该类还未被加载到内存中,则系统会加载此类:

一个类的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。

(1)加载:就是将class文件读入内存,并为之创建一个Class对象,任何类被使用时系统都会建立一个Class对象连接  

(2)验证:是否有正确的内部结构,并和其他类协调一致 

(3)准备:负责为类的静态成员分配内存,并设置默认初始化值

3、Cass类(名),是所有类的顶级类。

以下说明什么是反射:

4、假设,Person 是一个类(名),则通过此类名,可获得此类在内存中的“起始地址”(即引用),方法有三种,如下: 

   //第一种方法,直接通过Person类来获取字节码
  Class cls1 = Person.class;
  //第二种方法,通过类的实例来获取Person类的字节码
  Person person = new Person();
  Class cls2 = person.getClass();
  //第三种方法,调用Class类的静态方法来获取对应类的字节码,该方法会抛出异常
  Class cls3 = Class.forName("Person");
上述 cls1/2/3,是Person类“初始化对象“的引用。引用:即变量名--内存地址对应表
5、还或获取Person类(即其初始化对象)的三大”成份“---也是三大类:属性Field、方法Method、构造器Constructor等等
(1)获取类的构造方法:
//定义Person类:
class Person{
    public Person(){System.out.println("无参构造方法");}
    public Person(int i){System.out.println("带参构造方法");}
}       
//则可如下反射:
Class cls = Person.class;//获取Person类的字节码 (初始化对象的引用) Constructor constructor1 = cls.getConstructor();//调用getConstructor(),获取Person无参构造方法(的引用) Person p1 = (Person) constructor1.newInstance();//通过调用newInstance(),来执行无参构造方法 Constructor constructor2 = cls.getConstructor(int.class);//调用getConstructor(*.class),获取Person带参构造方法 Person p2 = (Person) constructor2.newInstance(1);//通过调用newInstance(int),来执行带参构造方法

控制台输出:

无参构造方法
带参构造方法

(2)获取类的属性:
//假设定义类:
class Person{ public Person(String name, int age){//类的构造方法 this.name = name; this.age = age; } public String name; private int age;//对于某些人来说,年龄是秘密! }
则:
Person p = new Person("小红", 20);//生产一个类的对象。name="小红”,age=20

Class cls = Class.forName("com.net168.test.Person");//通过类名(类的初始化对象),得类的引用
Field fieldName = cls.getField("name"); //得到初始化对象cls的name属性,初始化对象所有属性值为空
//fieldNmae的值是小红吗?错!它只是代表Person类身上name的这个变量,并没有对应到对象身上
//System.out.println(fieldNmae);
//fieldNmae不代表具体的值,只代表一个变量,所以我们需要传入一个person实例才能获取到其对应的值
//System.out.println(fieldName.get(p));

(3)成员方法的反射:
Person p = new Person();
        Class cls = p.getClass();//获取Person的字节码
        //获取setName()方法,需要传入参数为String
        Method method1 = cls.getMethod("setName", String.class);
        method1.invoke(p, "小明");//关联p,输入“小明”并执行该方法
        //获取getName()方法,无参则设为null
        Method method2 = cls.getMethod("getName", null);
        String name = (String) method2.invoke(p, null);//invoke返回的类型为Object
        System.out.println(name);
        //获取静态方法,由于静态方法只依赖与类,所以不需要提供具体的实例
        Method method3 = cls.getMethod("show", int.class);
//        method3.invoke(p, 1);提供具体实例p也可通过编译
        method3.invoke(null, 1);
        
    }
}

class Person{    
    public String name;
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
        System.out.println("设置name值为:" + name);
    }
    public static void show(int i){
        System.out.println("这是一个静态方法:" + i);
    }
}
6、总结:
(1)定义,并加载了一个类,则在内存中,创建了一个初始化对象
(2)通过类名(或对象名),可“反射”出此类的引用--------(实为初始化对象的)引用(内存中的始址)
(3)通过类的引用,又可反射出属性、方法、构造的引用,且通过其引用,调用方法,给属性赋值。
 
此文JAVA语句,摘自:作者:enjoy风铃
出处:http://www.cnblogs.com/net168/
 
 


猜你喜欢

转载自www.cnblogs.com/godzoo/p/9784781.html