搜索 K
Appearance
博客正在加载中...
Appearance
要了解反射,就得先知道 Java 代码在运行时期的三个阶段

Person.class 里面包含了类的名字、类的成员变量、类的构造方法和类的成员方法等。
例如定义一个类 Person
public class Person{
public String name;
private int age;
public Person(){}
public void eat(){}
}Person.java
↓
通过 Javac 命令编译
↓
Person.class 字节码文件,里面存放了三类重要的方法
Person.java 和 Person.class 都是文件,还没被加载进内存。
类加载器 ClassLoader 将字节码文件加载进内存。因为我们要创建一个对象,那么首先得知道这个类有什么信息,例如有什么成员变量、有什么构造方法和普通方法,这样我们才能创建对象。
那么,这个类的信息用什么来表示呢?在 Java 中,万物皆对象,有个类的名字就是 Class,用来表示字节码文件里的信息
Class Class<T>我们平时用的 String 类型,Random 类型,都是靠 Class 对象来创建实例的:
┌───────────────────────────┐
│ Class Instance │──────> String
├───────────────────────────┤
│name = "java.lang.String" │
└───────────────────────────┘
┌───────────────────────────┐
│ Class Instance │──────> Random
├───────────────────────────┤
│name = "java.util.Random" │
└───────────────────────────┘
┌───────────────────────────┐
│ Class Instance │──────> Runnable
├───────────────────────────┤
│name = "java.lang.Runnable"│
└───────────────────────────┘不管什么字节码文件,都有
┌───────────────────────────┐
│ Class Instance │──────> String
├───────────────────────────┤
│name = "java.lang.String" │
├───────────────────────────┤
│package = "java.lang" │
├───────────────────────────┤
│super = "java.lang.Object" │
├───────────────────────────┤
│interface = CharSequence...│
├───────────────────────────┤
│field = value[],hash,... │
├───────────────────────────┤
│method = indexOf()... │
└───────────────────────────┘而这些信息,也都是用对象来表示的。
所以我们后续就围绕这几个类来学习:
Class:任何运行在内存中的所有类都是该 Class 类的实例对象,每个 Class 类对象内部都包含了本来的所有信息。记着一句话,通过反射干任何事,先找 Class 准没错!可以说通过 Class 实例获取 class 信息的方法称为反射(Reflection)。Field:描述一个类的属性,内部包含了该属性的所有信息,例如数据类型,属性名,访问修饰符······Constructor:描述一个类的构造方法,内部包含了构造方法的所有信息,例如参数类型,参数名字,访问修饰符······Method:描述一个类的所有方法(包括抽象方法),内部包含了该方法的所有信息,与 Constructor 类似,不同之处是 Method 拥有返回值类型信息,因为构造方法是没有返回值的。此时类已被加载进内存,可以 new 对象了。
换句话说,也就是我们可以通过类加载器获取到某个类的信息(有什么成员变量、构造方法和普通方法),然后就可以通过它使用该类了
关于类加载器,我们这里不展开,后续再说。