Java中的反射机制
1、什么是Java中的反射机制?
在运行状态下,对任意一个类,都能知道该类的属性和方法;对于任意一个对象,都能调用他的属性和方法;这种动态获取的信息以及动态调用对象方法的功能就称为Java的反射机制。
2、Java的反射机制有什么用?
①运行时判断任意一个对象所属的类;
②运行时构造任意一个类的对象;
③运行时判断任意一个类所具有的成员变量及方法;
④在运行时调用任意一个对象的方法;
⑤生成动态代理。
3、相关的API
1,获取完整包名和类名
“`
package cn.test.com;
public class ReflectTest {
public static void main(String[] args) {
ReflectTest reflectTest = new ReflectTest();
System.out.println(reflectTest.getClass().getName());
//结果cn.test.com.ReflectTest
}
}
2,实例化class对象
package cn.test.com;
public class ReflectTest {
public static void main(String[] args) {
Class<?> clazz1 = null;
Class<?> clazz2 = null;
Class<?> clazz3 = null;
try {
clazz1 = Class.forName("cn.test.com.ReflectTest");//抛异常
clazz2 = new ReflectTest().getClass();
clazz3 = ReflectTest.class;
System.out.println("类名1: "+clazz1.getName()+" 类名2: "
+clazz2.getName()+" 类名3: "+clazz3.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//结果
//类名1: cn.test.com.ReflectTest
//类名2: cn.test.com.ReflectTest
//类名3: cn.test.com.ReflectTest
}
3,获取父类对象及实现接口
package cn.test.com;
import java.io.Serializable;
public class ReflectTest implements Serializable{
public static void main(String[] args) {
try {
//获取class对象
Class<?> clazz = Class.forName("cn.test.com.ReflectTest");
//获取父类对象
Class<?> supperClass = clazz.getSuperclass();
System.out.println("父类: "+supperClass.getName());
//结果--->父类: java.lang.Object
//获取所有实现的接口
Class<?>[] interfaces = clazz.getInterfaces();
for(Class<?> inter : interfaces){
System.out.println("接口有: "+inter.getName());
//接口有: java.io.Serializable
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
4,获取class中的所有构造函数
public static void main(String[] args) throws Exception {
Class<?> clazz = null;
clazz = Class.forName("cn.test.com.ReflectTest");
//方法一:实例化默认构造函数,调用set赋值
/*ReflectTest reflectTest = (ReflectTest) clazz.newInstance();
reflectTest.setName("test");
reflectTest.setAge(18);
System.out.println("name: "+reflectTest.getName()+" age: "+reflectTest.getAge());
*/
//方法二:获取所有的构造函数,使用构造函数赋值
Constructor<?>[] constructors = clazz.getConstructors();
for(int i=0;i<constructors.length;i++){
//获取构造函数中的参数列表
Class<?>[] parameterTypes = constructors[i].getParameterTypes();
//遍历参数列表
System.out.print("constructor:(");
for(int j=0;j<parameterTypes.length;j++){
System.out.print(parameterTypes[j].getName()+" ");
}
System.out.print(")");
System.out.println();
//constructor:()
//constructor:(java.lang.String int )
}
ReflectTest reflectTest = (ReflectTest) constructors[1].newInstance("test",12);
System.out.println(reflectTest);
//ReflectTest [name=test, age=12]
}
5,获取class类中的全部属性
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("cn.test.com.ReflectTest");
/*-----------获取本类属性--------------*/
//获取所有属性
Field[] fields = clazz.getDeclaredFields();
for(Field field:fields){
//获取权限修饰符
int modifier = field.getModifiers();
//获取修饰符名称
String modifierName = Modifier.toString(modifier);
System.out.println("modifierName: "+modifierName);
//获取属性类型
Class<?> type = field.getType();
System.out.println(type.getName());
}
/*-----------获取父类或实现类属性--------------*/
Field[] supperFields = clazz.getFields();
for(Field supperField : supperFields){
int modifier = supperField.getModifiers();
String modifierName = Modifier.toString(modifier);
System.out.println("modifierName: "+modifierName);
Class<?> type = supperField.getType();
System.out.println(type.getName());
}
}
6,获取class中的全部方法
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("cn.test.com.ReflectTest");
Method[] methods = clazz.getMethods();
for(Method method : methods){
//获取返回值类型
Class<?> returnType = method.getReturnType();
System.out.println("returnType: "+returnType.getName());
//获取当前方法的参数列表
Class<?>[] parameterTypes = method.getParameterTypes();
//获取方法修饰符
int modifier = method.getModifiers();
System.out.println(Modifier.toString(modifier));
for(Class<?> parameterType : parameterTypes){
System.out.print(parameterType.getName());
}
//获取该方法的异常类型
Class<?>[] exceptionTypes = method.getExceptionTypes();
for(Class<?> exceptionType:exceptionTypes){
System.out.println(exceptionType.getName());
}
}
}
7,通过反射机制调用class的某个方法
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("cn.test.com.ReflectTest");
//获取某个特定的方法
Method method = clazz.getMethod("toString");
//调用方法:底层方法对象及参数类型
method.invoke(clazz.newInstance());
Method method2 = clazz.getMethod("test",String.class);
method2.invoke(clazz.newInstance(),"test");
//反射类中必须存在该方法及对应的参数类型
}
4、反射机制的应用
反射机制最为常见的是在spring的工厂模式、动态代理以及与配置文件相结合使用。