1.java中执行类的过程
通过编译器将.java文件编译成字节码文件.class,由jvm解释执行,通过类加载器加载字节码文件,再交给Java运行系统,之后交给操作系统,最后再到物理硬件上运行。如下图:
2.什么是反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。反射就是把java类中的各种成分映射成一个个的Java对象,然后在运行期间动态加载类加载器中的字节码文件(字节码文件中包含类的元信息),进行操作。
3.实例化对象的内存模型
实例化一个对象后,Java会自动创建.class文件,再有JVM加载这个.class文件,在方法区中动态创建.class的实例。调用构造函数,在堆中创建类的非静态属性以及非静态方法的引用,把堆中这个对象的地址压栈。反射就是通过.class实例动态的加载类中信息。
ps:java1.7后方法区在堆中;反射是在运行期操作class对象;
4.类中的元信息
- 类名称/全名称/访问修饰符(Class)
- 属性:名称/类型/访问修饰符(Field)
- 方法:方法名称/方法返回类型/方法参数列表/方法参数个数/访问修饰符(Method)
- 构造函数:访问修饰符/构造函数名称(Constructor)
ps:访问修饰符有几种:
private/protected/默认的/public
5.代码(有省略部分)
定义一个Person类(省略set,get方法)
import java.io.Serializable;
/**
* person类
*/
public class Person implements Serializable {
private Integer personId;
public String personName;
private int personAge;
}
反射的三种方式:
通过.class直接获取;通过classForName方法;通过类的实例获取
public class ReflectDemo {
@Test //获取一个类的Class对象的方式
public void testCreateClass() throws ClassNotFoundException {
//通过.class获取
System.out.println(Person.class);
//通过Class对象中的classForName()这个静态方法
Class<?> aClass = Class.forName("com.entity.Person");
System.out.println(aClass);
//通过类的实例获取
Person person = new Person();
System.out.println(person.getClass());
}
}
得到结果如下:
反射中的常用API:
类(Class),属性(Field),方法(Method),构造器(Constructor)