Java反射API
Java反射机制提供的功能
-
获取一个类的所有成员变量及方法(含构造方法(有/无 参数))
-
创建一个类的对象:
1、获取一个对象具有的成员变量及赋值
2、调用一个对象的方法
3、判断一个对象所属的类
java.lang.Class 类
java.lang.Class类是反射机制的基础
Class存放着对应类型对象的运行时信息
-
在Java程序运行时,Java虚拟机为所有类型维护一个java.lang.Class对象
-
该Class对象存放着所有关于该对象的 运行时信息
-
泛型形式为Class< T >
Java反射机制的实现除了依靠Java.lang.Class类,还需要依靠:Constructor类、Field类、Method类:
- Class类
类对象
- Constructor类
类的构造器对象
- Field类
类的属性对象
- Method类
类的方法对象
使用
在使用Java反射机制时,主要步骤包括:
-
- 获取 目标类型的Class对象
-
- 通过 Class 对象分别获取Constructor类对象、Method类对象 & Field 类对象
-
- 通过 Constructor类对象、Method类对象 & Field类对象分别获取类的构造函数、方法&属性的具体信息,并进行后续操作
获取目标类型的Class对象
public class T {
public static void main(String[] args) throws ClassNotFoundException {
//Object.getClass()
String s = "test";
Class<?> class_ = s.getClass();
System.out.println(class_);
//输出
//class java.lang.String
System.out.println("-------------------------------");
//T.class
Class<?> class_1 = Double.class;
System.out.println(class_1);
//输出
//class java.lang.Double
System.out.println("-------------------------------");
// /Class.forName
Class<?> class_2 = Class.forName("java.lang.Character");
System.out.println(class_2);
//输出
//class java.lang.Character
System.out.println("-------------------------------");
//TYPE语法
Class<?> classType = Boolean.TYPE;
System.out.println(classType);
// 输出
//boolean
}
}
通过Class对象分别获取Constructor类对象、Method类对象 & Field 类对象
Class类中的方法:
获取类的构造函数(传入构造函数的参数类型)
-
获取指定的构造函数 (公共 / 继承)
Constructor getConstructor(Class<?>… parameterTypes) -
获取所有的构造函数(公共 / 继承)
Constructor<?>[] getConstructors() -
获取指定的构造函数 ( 不包括继承)
Constructor getDeclaredConstructor(Class<?>… parameterTypes) -
获取所有的构造函数( 不包括继承)
Constructor<?>[] getDeclaredConstructors()
例子:
public class T1 {
public static void main(String[] args) throws NoSuchMethodException {
Class<?> class_ = Data.class;
Constructor constructor = class_.getConstructor(int.class);
System.out.println(constructor);
System.out.println("------------");
for (Constructor c:class_.getConstructors()) {
System.out.println(c);
//public better_write.Learn_reflection.A2.Data(int,double,java.lang.String,float,char)
//public better_write.Learn_reflection.A2.Data(float,char)
//public better_write.Learn_reflection.A2.Data()
//public better_write.Learn_reflection.A2.Data(int,double,java.lang.String)
}
System.out.println("------------");
for (Constructor c : class_.getDeclaredConstructors()) {
System.out.println(c);
//private better_write.Learn_reflection.A2.Data(double,java.lang.String,float)
//public better_write.Learn_reflection.A2.Data(int,double,java.lang.String,float,char)
//public better_write.Learn_reflection.A2.Data(float,char)
//public better_write.Learn_reflection.A2.Data()
//public better_write.Learn_reflection.A2.Data(int,double,java.lang.String)
//public better_write.Learn_reflection.A2.Data(int)
}
System.out.println("------------");
}
}
不带 "Declared"的方法支持取出包括继承、公有(Public) & 不包括有(Private)的构造函数
带 "Declared"的方法是支持取出包括公共(Public)、保护(Protected)、默认(包)访问和私有(Private)的构造方法,但不包括继承的构造函数
获取类的属性(传入属性名)
-
获取指定的属性(公共 / 继承)
Field getField(String name) -
获取所有的属性(公共 / 继承)
Field[] getFields() -
获取指定的所有属性 (不包括继承)
Field getDeclaredField(String name) -
获取所有的所有属性 (不包括继承)
Field[] getDeclaredFields()
public class T2 {
public static void main(String[] args) throws NoSuchFieldException {
Class<?> class_ = Data.class;
for (Field f : class_.getFields()) {
System.out.println(f);
//public java.lang.String better_write.Learn_reflection.A2.Data.string
}
System.out.println("-----------------------------");
Field f1 = class_.getField("aShort");
//public short better_write.Learn_reflection.A2.Data.aShort
System.out.println(f1);
}
}
获取类的方法(传入方法名 & 参数类型)
-
获取指定的方法(公共 / 继承)
Method getMethod(String name, Class<?>… parameterTypes) -
获取所有的方法(公共 / 继承)
Method[] getMethods() -
获取指定的方法 ( 不包括继承)
Method getDeclaredMethod(String name, Class<?>… parameterTypes) -
获取所有的方法( 不包括继承)
Method[] getDeclaredMethods()
public class T3 {
public static void main(String[] args) throws NoSuchMethodException {
Class<?> class_ = Data.class;
for (Method m : class_.getMethods()) {
System.out.println(m);
//public static int better_write.Learn_reflection.A2.Data.m1(int,int)
//public final void java.lang.Object.wait() throws java.lang.InterruptedException
//public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
//public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
//public boolean java.lang.Object.equals(java.lang.Object)
//public java.lang.String java.lang.Object.toString()
//public native int java.lang.Object.hashCode()
//public final native java.lang.Class java.lang.Object.getClass()
//public final native void java.lang.Object.notify()
//public final native void java.lang.Object.notifyAll()
}
System.out.println("--------------------------------------------");
Method m1 = class_.getMethod("m1", int.class, int.class);
//public static int better_write.Learn_reflection.A2.Data.m1(int,int)
System.out.println(m1);
System.out.println("--------------------------------------------");
Method m2 = class_.getMethod("m5");
//public void better_write.Learn_reflection.A2.Data.m5()
System.out.println(m2);
}
}
通过 Constructor类对象、Method类对象 & Field类对象分别获取类的构造函数、方法 & 属性的具体信息 & 进行操作
通过Constructor 类对象获取类构造函数信息
-
String getName();// 获取构造器名
-
Class getDeclaringClass();// 获取一个用于描述类中定义的构造器的Class对象
-
int getModifiers();// 返回整型数值,用不同的位开关描述访问修饰符的使用状况
-
Class[] getParameterTypes();// 获取一个用于描述参数类型的Class对象数组
public class T4 {
public static void main(String[] args) {
Class<?> class_ = Data.class;
for (Constructor c:class_.getConstructors()) {
System.out.println(c.getName());
System.out.println("");
System.out.println(c.getDeclaringClass());
System.out.println("");
System.out.println(c.getModifiers());
System.out.println("");
for (Class cc : c.getParameterTypes()) {
System.out.println("para class type " + cc);
}
System.out.println("---------------------------------------------------");
}
}
}
通过Field类对象获取类属性信息
-
String getName();// 返回属性的名称
-
Class getDeclaringClass(); // 获取属性类型的Class类型对象
-
Class getType();// 获取属性类型的Class类型对象
-
int getModifiers(); // 返回整型数值,用不同的位开关描述访问修饰符的使用状况
-
Object get(Object obj) ;// 返回指定对象上 此属性的值
-
void set(Object obj, Object value) // 设置 指定对象上此属性的值为value
public class T6 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
Class<?> class_ = Data.class;
for (Field f : class_.getFields()) {
System.out.println(f.getName());
System.out.println("");
System.out.println(f.getDeclaringClass());
System.out.println("");
System.out.println(f.getType());
System.out.println("");
System.out.println("-------------------------");
}
System.out.println("********");
Data data = (Data) class_.newInstance();
Field f1 = class_.getField("string");
f1.set(data,"ass");
System.out.println(data.getString());
System.out.println(f1.get(data));
}
}
通过Method 类对象获取类方法信息
-
String getName();// 获取方法名
-
Class getDeclaringClass();// 获取方法的Class对象
-
int getModifiers();// 返回整型数值,用不同的位开关描述访问修饰符的使用状况
-
Class[] getExceptionTypes();// 获取用于描述方法抛出的异常类型的Class对象数组
-
Class[] getParameterTypes();// 获取一个用于描述参数类型的Class对象数组
public class T5 {
public static void main(String[] args) {
Class<?> class_ = Data.class;
for (Method m : class_.getMethods()) {
System.out.println(m.getName());
System.out.println("");
System.out.println(m.getDeclaringClass());
System.out.println("");
System.out.println(m.getModifiers());
System.out.println("");
for (Class cc : m.getParameterTypes()) {
System.out.println("para : " + cc);
}
System.out.println("---------------------");
}
}
}
结合使用
public class T9 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
Class<?> class_ = Class.forName("better_write.Learn_reflection.A2.Data");
Data d1 = (Data) class_.newInstance();
d1.setaChar('a');
System.out.println(d1.getaChar());
Field char_field = class_.getDeclaredField("aChar");
char_field.set(d1,'l');
System.out.println(d1.getaChar());
System.out.println(char_field.get(d1));
System.out.println("--------------------------------------------");
Data d2 = (Data) class_.getConstructor(float.class,char.class).newInstance(12f,'4');
System.out.println(d2);
Method m1 = class_.getDeclaredMethod("m2");
m1.setAccessible(true);
m1.invoke(d1);
Method m2 = class_.getDeclaredMethod("m4");
m2.invoke(d1);
}
}