1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class Car {
private String brand;
private String color;
private int maxSpeed;
public Car() {}
public void setBrand(String brand) { this.brand = brand; }
public void setColor(String color) { this.color = color; }
public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; }
@Override public String toString() { return "Car{" + "brand='" + brand + '\'' + ", color='" + color + '\'' + ", maxSpeed=" + maxSpeed + '}'; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import java.lang.reflect.Constructor; import java.lang.reflect.Method;
public class ReflectTest {
public static Car initByDefaultConst() throws Throwable {
ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class clazz = loader.loadClass("Car");
Constructor cons = clazz.getDeclaredConstructor((Class[])null); Car car = (Car)cons.newInstance();
Method setBrand = clazz.getMethod("setBrand", String.class); setBrand.invoke(car, "benz"); Method setColor = clazz.getMethod("setColor", String.class); setColor.invoke(car, "黑色"); Method setMaxSpeed = clazz.getMethod("setMaxSpeed", int.class); setMaxSpeed.invoke(car, 200); return car; }
public static void main(String[] args) throws Throwable { Car car = initByDefaultConst(); System.out.println(car); } }
|
类加载器是寻找类的字节码文件并构造出类在JVM内部表示对象的组件。
类加载器把一个类装入JVM中,需要经过以下步骤:
(1)装载:查找和导入Class文件
(2)链接:执行校验、准备和解析(可选)步骤
* 校验:检查载入Class文件数据的正确性
* 准备:给类的静态变量分配存储空间
* 解析:将符号引用转换成直接引用
(3)初始化:对类的静态变量、静态代码块执行初始化工作
类装载工作由ClassLoader及其子类负责。JVM在运行时会产生3个ClassLoader:根装载器、ExtClassLoader(拓展类装载器)和AppClassLoader(应用类装载器)。
根装载器不是ClassLoader的子类,它使用C++编写,因而在Java中看不到它,它负责装载JRE的核心类库
ExtClassLoader和AppClassLoader都是ClassLoader的子类,ExtClassLoader负责装载JRE拓展目录ext中的jar包,AppClassLoader负责装载classpath路径下的类包。
1 2 3 4 5 6 7 8 9
| public class ClassLoaderTest {
public static void main(String[] args) { ClassLoader loader = Thread.currentThread().getContextClassLoader(); System.out.println("current loader = " + loader); System.out.println("parent loader = " + loader.getParent()); System.out.println("grandparent loader = " + loader.getParent().getParent()); } }
|
1 2 3
| current loader = sun.misc.Launcher$AppClassLoader@18b4aac2 parent loader = sun.misc.Launcher$ExtClassLoader@60e53b93 grandparent loader = null
|
每个类在JVM中都拥有一个对应的java.lang.Class对象,它提供了类结构信息的描述。数组、枚举、注解及基本Java类型,甚至void都拥有对应的Class对象。Class没有public的构造方法。Class对象是在装载类时由JVM通过调用类装载器中的defineClass()方法自动构造的。
Class反射对象描述类语义结构,可以从Class对象中获取构造函数、成员变量、方法类等元素的反射对象,并通过反射对象对目标类对象进行操作:
- Constuctor:类的构造函数反射类
- Method:类方法的反射类
- Field:类的成员变量的反射类
参考:《精通Spring 4.x 企业应用开发实战》