参考https://blog.csdn.net/liujiahan629629/article/details/18013523
参考https://blog.csdn.net/codejas/article/details/78635926
反射
Class类
Class类
- Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成 java.lang.Class类的一个实例(Class 对象)。也就是说,在 Java 中,每个 java 类都有一个相应的 Class 对象,用于表示这个 java 类的类型信息。即用来保存程序运行时类的信息的类。
- 类初始化,类被加载之后,jvm 已经获得了一个描述类结构的 Class 实例。但是还需要进行类初始化操作之后才能正常使用此类,类初始化操作就是执行一遍类的静态语句,包括静态变量的声明还有静态代码块。
获取类的字节码(Class)对象的三种方式
- 类.class
- 对象.getClass()
- Class.forName() 要求JVM查找并加载指定的类,如果在类中有静态初始化器的话,JVM必然会执行该类的静态代码段。
public class Reflect1 {
public static void main(String[] args) throws Exception {
Wangba c = new Wangba();
Class c1 = Wangba.class;
Class c2 = Class.forName("Wangba");
Class c3 = c.getClass();
System.out.println(c1+"---"+c2+"---"+c3);
boolean b = (c1==c2)&&(c2==c3);
System.out.println(b);
}
}
class Wangba {
}
newInstance
- newInstance使用类加载机制创建对象,使用newInstance之前这个类必须已经加载并连接了;可以说newInstance将new这个方式分解为两步,先加载类,再实例化。
- 可以降低耦合性,下面是具体例子
Class c = Class.forName("A");
factory = (AInterface)c.newInstance();
String className = "A";
Class c = Class.forName(className);
factory = (AInterface)c.newInstance();
//从xml 配置文件中获得字符串
String className = readfromXMlConfig;
Class c = Class.forName(className);
factory = (AInterface)c.newInstance();
- Class.newInstance 自动调用类的无参构造函数,且只能调用无参构造函数
public class Reflect {
public static void main(String[] args) throws Exception {
Class c1 = Class.forName("Wangba");
Object o1 = c1.newInstance();
Class c2 = Wangba.class;
Object o2 = c2.newInstance();
}
}
class Wangba {
Wangba(){
System.out.println("一只千年的王八");
}
}
- Constructor.newInstance() 可以根据传入的参数,调用任意构造构造函数,具体见下面一节。
构造
- getConstructors()
- getDeclaredConstructors()
- getConstructor()
- getDeclaredConstructor()
- 获取私有构造方法时要采用破解的方式
import java.lang.reflect.Constructor;
public class Constr {
public static void main(String[] args) throws Exception {
Class c = Class.forName("P");
Constructor[] con1 = c.getConstructors();
Constructor[] con2 = c.getDeclaredConstructors();
System.out.println("下面是公有构造方法");
for(int i=0;i<con1.length;i++) {
System.out.println(con1[i]);
}
System.out.println("下面是所有构造方法");
for(int i=0;i<con2.length;i++) {
System.out.println(con2[i]);
}
Constructor con3 = c.getDeclaredConstructor(int.class,int.class);
con3.setAccessible(true);
P p1 = (P) con3.newInstance(1,2);
//=================================
Constructor con4 = c.getDeclaredConstructor(String.class,String.class);
P p2 = (P) con4.newInstance("a","b");
}
}
class P{
P(){
System.out.println("获取了无参构造方法");
}
P(int a){
System.out.println();
}
public P(int a,String b){
System.out.println();
}
private P(int a,int b){
System.out.println("获取了私有构造方法");
}
protected P(String a,String b){
System.out.println("获取了保护构造方法");
}
}
成员变量
- getFields()
- getDeclaredFields()
- getField(String fieldName)
- getDeclaredField(String fieldName)
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class Constr {
public static void main(String[] args) throws Exception {
Person p = (Person) Class.forName("Person").getDeclaredConstructor().newInstance();
Field f = Class.forName("Person").getDeclaredField("name");
f.set(p, "猪八戒");
System.out.println(p.name);
}
}
class Person{
Person(){
}//默认是default,不加Declared的只能获取公有型属性或方法
String name;
}
成员方法
- getMethods()
- getDeclaredMethods()
- getMethod(String name,Class<?>… parameterTypes)
- getDeclaredMethod(String name,Class<?>… parameterTypes)
- 获取成员方法后使用invoke执行
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Constr {
public static void main(String[] args) throws Exception {
Method m1 = Class.forName("Person").getMethod("cry");
Method m3 = Class.forName("Person").getMethod("cry",String.class);
Person p = (Person) Class.forName("Person").getDeclaredConstructor().newInstance();
m1.invoke(p);
m3.invoke(p, "猪八戒");
}
}
class Person{
Person(){
}//默认是default,不加Declared的只能获取公有型属性或方法
String name;
public void cry() {
System.out.println("哭");
}
public void cry(String a) {
System.out.println(a+"哭");
}
}