假设现在有一个类 Car
package reflection;
class Car {
private String brand;
private String color;
private int maxSpeed;
//①默认构造函数
public Car() {
}
//②带参构造函数
public Car(String brand, String color, int maxSpeed) {
this.brand = brand;
this.color = color;
this.maxSpeed = maxSpeed;
}
//③未带参的方法
public void introduce() {
System.out.println("brand:" + brand + ";color:" + color + ";maxSpeed:" + maxSpeed);
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
}
这是另外的一个类 ReflectTest
package reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ReflectTest {
@SuppressWarnings("unchecked")
public static Car initByDefaultConst() throws Throwable {
//①通过类装载器获取Car类对象
ClassLoader loader = Thread.currentThread().getContextClassLoader();
ClassLoader loader1 = Car.class.getClassLoader();
System.out.println(loader.toString());
System.out.println(loader1.toString());
System.out.println(loader.equals(loader1));
System.out.println("------------------------");
Class clazz = loader.loadClass("reflection.Car");
Class clazz1 = loader1.loadClass("reflection.Car");
System.out.println(clazz.toString());
System.out.println(clazz1.toString());
System.out.println(clazz==clazz1);
System.out.println(clazz.equals(clazz1));
System.out.println("------------------------------");
//②获取类的默认构造器对象并通过它实例化Car
// Constructor cons = clazz.getDeclaredConstructor((Class[]) null);
// Constructor[] cons = clazz.getConstructors();
Constructor cons = clazz.getDeclaredConstructor();
System.out.println(cons.toString());
System.out.println(clazz.getDeclaredConstructor(String.class, String.class, int.class).toString());
Car car = (Car) cons.newInstance();
//③通过反射方法设置属性
Method setBrand = clazz.getMethod("setBrand", String.class);
setBrand.invoke(car, "红旗CA72");
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();
car.introduce();
}
}
主要看这部分,其他的都不重要
ClassLoader loader = Thread.currentThread().getContextClassLoader();
ClassLoader loader1 = Car.class.getClassLoader();
System.out.println(loader.toString());
System.out.println(loader1.toString());
System.out.println(loader.equals(loader1));
System.out.println("------------------------");
Class clazz = loader.loadClass("reflection.Car");
Class clazz1 = loader1.loadClass("reflection.Car");
System.out.println(clazz.toString());
System.out.println(clazz1.toString());
System.out.println(clazz==clazz1);
System.out.println(clazz.equals(clazz1));
System.out.println("------------------------------");
这是输出的结果
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$AppClassLoader@18b4aac2
true
------------------------
class reflection.Car
class reflection.Car
true
true
------------------------------
在大部分的时候,这两者基本是差不多的
Each class will use its own classloader to load other classes. So if ClassA.class references ClassB.class then ClassB needs to be on the classpath of the classloader of ClassA, or its parents.
每个 class 将会使用它自己的 classloader 来加载其他的 classes
所以如果 ClassB 需要位于 ClassA 的类加载器或其父代的类路径上
What does it mean to say that “ClassA.class references ClassB.class”?
When ClassA has an import statement for ClassB, or if there is a method in ClassA that has a local variable of type ClassB. That will trigger ClassB to be loaded, if it’s not loaded already.
ClassA.class 引用 ClassB.class 意味着,当 ClassA 具有 ClassB 的导入语句时,或者 ClassA 中有一个具有类型 ClassB 的局部变量的方法时。这将触发ClassB被加载,如果它尚未加载。
The thread context classloader is the current classloader for the current thread. An object can be created from a class in ClassLoaderC and then passed to a thread owned by ClassLoaderD. In this case the object needs to use Thread.currentThread().getContextClassLoader() directly if it wants to load resources that are not available on its own classloader.
thread context classloader 是当前线程的类加载器。
可以从 ClassLoaderC 中的类创建对象,然后将其传递给 ClassLoaderD 拥有的线程。
在这种情况下,如果对象需要加载其自己的类加载器上不可用的资源,则该对象需要直接使用 Thread.currentThread().getContextClassLoader()
reference
1、Difference between thread’s context class loader and normal classloader