1.java的反射机制
Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为 Java 语言的反射机制。简单来说,反射机制指的是程序在运行时能够获取自身的信息。在 Java 中,只要给定类的名字,就可以通过反射机制来获得类的所有信息。
2.反射的基础---Class
要想知道一个类的属性和方法,必须先获取到该类的字节码文件对象。获取类的信息时,使用的就是 Class 类中的方法。所以先要获取到每一个字节码文件(.class)对应的 Class 类型的对象.
class(包括interface)的本质是数据类型(Type)。class是由JVM在执行过程中动态加载的。JVM在第一次读取到一种class类型时,将其加载进内存。每加载一种class,JVM就为其创建一个Class类型的实例,并关联
2.1 什么是反射?
由于JVM为每个加载的class创建了对应的Class实例,并在实例中保存了该class的所有信息,包括类名、包名、父类、实现的接口、所有方法、字段(成员变量)等,因此,如果获取了某个Class实例,我们就可以通过这个Class实例获取到该实例对应的class的所有信息。这种通过Class实例获取class信息的方法称为反射(Reflection)。
2.2获取Class的三个方法:
- 通过一个Class的静态变量Class获取:
Class cls=String.class;
- 如果我们有一个实例变量,可以通过该实例变量提供的getClass()方法获取:
String s="Hello";
Class cls=s.getClass();
- 如果知道一个class的完整类名,可以通过静态方法Class.forName()获取:
Class cls=Class.forName("java.lang.String");
2.3 Class的常用方法
2.4动态加载机制
JVM在执行Java程序的时候,并不是一次性把所有用到的class全部加载到内存,而是第一次需要用到class时才加载。
Public class Main{
static{
System.out.println("Main被加载");
}
public static void main(String[] args){
int rand=new Random().nextInt(10);
if(rand>5){
create(rand);
}
}
static void create(int no){
Person p=new Person(no);
}
}
class Person{
static{
System.out.println("Person类被加载");
}
public Person(int no){
System.out.println("Person类的有参构造方法");
}
}
当执行Main.java时,由于用到了Main,因此,JVM首先会把Main.class加载到内存。然而,并不会加载Person.class,除非程序执行到create()方法,JVM发现需要加载Person类时,才会首次加载Person.class。如果没有执行create()方法,那么Person.class根本就不会被加载。
3.Constructor类
Constructor类用来描述类中所定义的构造方法。
1.得到类所有的构造方法
Constructor constructors[]=
Class.forName(“java.lang.String”).getConstructors();
2.得到类中某个具体的构造方法,在getConstructors中传入参数类型所对应的字节码
Constructor constructor=
Class.forName(“java.lang.String”).getConstructor(String.class)
使用Constructor类的目的是用来创建响应类的对象
正常情况:
String str = new String(“hello”);
反射情况:
Constructor con = String.class.getConstructor(String.class)
拿到string类型的构造方法
String str = (String)con.newlnstance(“hello”)
通过反射方式创建对象的过程
Class---->Constructor---->某个类的对象
只有当要用某个无参构造方法创建该类对象时,可以省略创建Constructor类对象的这个过程。
Date d = (Date)Class.forName(“java.util.Date”).newlnstance();
注意:java运行环境的缓存中保存了类的无参构造方法所对应的Constructor对象。
Field类
Field类是用来表示类中的属性(字段)
(1) Class.getPields0:得到Class对象的所有字段,返回的是riela数组。
(2) Class. getField (String: name)返回个 Field 对象,它反映此 Class对象所表示的类或接口的指定公有成员字段。
(3) Field的对象所代表的某-一个类的属性,而不是那个类的某一个对象的属性。要得到某个对象对应的属性值,需要通过get (0b ject obj)方法与某个对象具体关联
(4)对于非公有属性只能通过Class的getDec laredField (String fieldName)方法得到。
(5)对于私有属性要得到它所关联到的对象的值,需通过Field的setAccessible (boolean boolean)方法设置。
(6) Field类的getType Q方法用来得到字段所属的类型