动态特性:一段代码,改变其中的变量,将会导致这段代码产生功能性的变化。
Java反射机制是在运行状态时,对于任意一个类,都能够获取这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性(包括私用方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制。
public void execute(String className, String methodName) throws Exception {
Class clazz = Class.forName(className);
clazz.getMethod(methodName).invoke(clazz.newInstance());
}

当我们创建了一个类文件,经过javac编译之后,就会形成.class文件,同时JVM内存会查找生成的.class文件读入内存和经过ClassLoader加载,同时会自动创建生成一个Class对象,里面拥有其获取的成员变量,成员方法,和构造方法等。
JVM为每个加载的class创建了对应的Class实例,并在实例中保存了该class的所有信息。获取了某个Class实例,就可以通过这个Class实例获取到该实例对应的class的所有信息
如果你已经加载了某个类,可以直接通过一个class的静态变量class获取。使用.class来创建Class对象的引用时,不会自动初始化该Class对象。
Class cls = String.class;
如果上下文中存在某个类的实例,可以通过该实例变量提供的getClass()方法获取
String s = "nivia";
Class cls = s.getClass();
知道一个class的完整类名,可以通过静态方法Class.forName()获取。使用forName()会自动初始化该Class对象
Class cls = Class.forName("java.lang.String");
forName有两个函数重载
Class<?> forName(String name)
Class<?> forName(String name, **boolean** initialize, ClassLoader loader)
Class.forName(className)
// 等于
Class.forName(className, true, currentLoader)
第二个参数表示是否初始化,在 forName 的时候,构造函数并不会执⾏,而是执⾏类初始化。他会执行static{}静态块里面的内容
public class TrainPrint {
{
System.out.printf("Empty block initial %s\\\\n", this.getClass());
}
static {
System.out.printf("Static initial %s\\\\n", TrainPrint.class);
}
public TrainPrint() {
System.out.printf("Initial %s\\\\n", this.getClass());
}
}
当实例化这个类时,⾸先调⽤的是static {},其次是 {} ,最后是构造函数。其中static {}就是在类初始化的时候调用的
由于Class实例在JVM中是唯一的,所以,上述方法获取的Class实例是同一个实例
Field getField(name):根据字段名获取某个public的field(包括父类)
Field getDeclaredField(name):根据字段名获取当前类的某个field(不包括父类)
Field[] getFields():获取所有public的field(包括父类)
Field[] getDeclaredFields():获取当前类的所有field(不包括父类)