Java反射
一、什么是反射Reflect
反射(Reflect)是在运行时动态访问类与对象的技术。
反射是JDK1.2版本后的高级特性,隶属于java.lang.reflect。
大多数Java框架都基于反射实现参数配置、动态注入等特性。
二、反射的核心类
1、Class类
Class是JVM中代表“类和接口”的类。
Class对象具体包含了某个特定类的结构信息。
通过Class对象可以获取对应类的构造方法、方法、成员变量
Class核心方法
public class ClassSample{
public static void main(String[] args){
try{
//Class.forName()方法将指定的类加载到jvm,并返回对应Class对象
Class employeeClass = Class.forName("com.reflect.entity.Employee");
//newInstance通过默认构造方法创建新的对象
Employee emp = (Employee)employeeClass.newInstance();
}catch(ClassNotFoundException e){
//类名与类路径书写错误时抛出“类无法找到”异常
e.printStackTrace();
}catch(IllegalAccessException e){
//非法访问异常,当在作用域外访问对象方法或成员变量时抛出
e.printStackTrace();
}catch(InstantiationException e){
//对象无法被实例化,抛出“实例化异常”
e.printStackTrace();
}
}
}
2、Constructor构造方法类
Constructor类是对Java类中的构造方法的抽象。
Constructor对象包含了具体类的某个具体构造方法的声明。
通过Constructor对象调用带参构造方法创建对象。
Constructor类核心方法
public class ConstructorSample{
public static void main(String[] args){
try{
//Class.forName()方法将指定的类加载到jvm,并返回对应Class对象
Class employeeClass = Class.forName("com.reflect.entity.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class,String.class,Float.class,String.class
});
Employee employee = (Employee)constructor.newInstance(new Object[]{
100,"张三",5000f,"研发部"
});
}catch(ClassNotFoundException e){
//类名与类路径书写错误时抛出“类无法找到”异常
e.printStackTrace();
}catch(NoSuchMethodException e){
//没有找到与之对应格式的方法
e.printStackTrace();
}catch(IllegalAccessException e){
//非法访问异常,当在作用域外访问对象方法或成员变量时抛出
e.printStackTrace();
}catch(InstantiationException e){
//对象无法被实例化,抛出“实例化异常”
e.printStackTrace();
}catch(InvocationTargetException e){
//当被调用的方法的内部抛出了异常而没有被捕获时
e.printStackTrace();
}
}
}
3、Method方法类
Method对象指代某个类中的方法的描述。
Method对象使用classObj.getMethod()方法获取。
通过Method对象调用指定对象的对应方法。
Method类核心方法
public class MethodSample{
public static void main(String[] args){
try{
//Class.forName()方法将指定的类加载到jvm,并返回对应Class对象
Class employeeClass = Class.forName("com.reflect.entity.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class,String.class,Float.class,String.class
});
Employee employee = (Employee)constructor.newInstance(new Object[]{
100,"张三",5000f,"研发部"
});
Method updataSalaryMethod = employeeClass.getMethod("updateSalary",new Class[]{
Float.class
});
updataSalaryMethod.invoke(employee,new Object[]{1000f});
}catch(ClassNotFoundException e){
//类名与类路径书写错误时抛出“类无法找到”异常
e.printStackTrace();
}catch(NoSuchMethodException e){
//没有找到与之对应格式的方法
e.printStackTrace();
}catch(IllegalAccessException e){
//非法访问异常,当在作用域外访问对象方法或成员变量时抛出
e.printStackTrace();
}catch(InstantiationException e){
//对象无法被实例化,抛出“实例化异常”
e.printStackTrace();
}catch(InvocationTargetException e){
//当被调用的方法的内部抛出了异常而没有被捕获时
e.printStackTrace();
}
}
}
4、Field成员变量类
Field对应某个具体类中的成员变量的声明。
Field对象使用classObj.getField()方法获取。
通过Field对象可为某对象成员变量赋值、取值。
Field类核心方法
public class FieldSample{
public static void main(String[] args){
try{
//Class.forName()方法将指定的类加载到jvm,并返回对应Class对象
Class employeeClass = Class.forName("com.reflect.entity.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class,String.class,Float.class,String.class
});
Employee employee = (Employee)constructor.newInstance(new Object[]{
100,"张三",5000f,"研发部"
});
Field enameField = employeeClass.getField("ename");
enameField.set(employee, "李四");
String ename = (String)enameField.get(employee);
}catch(ClassNotFoundException e){
//类名与类路径书写错误时抛出“类无法找到”异常
e.printStackTrace();
}catch(NoSuchMethodException e){
//没有找到与之对应格式的方法
e.printStackTrace();
}catch(IllegalAccessException e){
//非法访问异常,当在作用域外访问对象方法或成员变量时抛出
e.printStackTrace();
}catch(InstantiationException e){
//对象无法被实例化,抛出“实例化异常”
e.printStackTrace();
}catch(InvocationTargetException e){
//当被调用的方法的内部抛出了异常而没有被捕获时
e.printStackTrace();
}catch(NoSuchFieldException e){
//没有找到对应成员变量时抛出的异常
e.printStackTrace();
}
}
}
5、getDeclared系列方法
getDeclaredContructor(s)|Method(s)|Field(s)获取对应所有对象。
public class getDeclaredSample{
public static void main(String[] args){
try{
//Class.forName()方法将指定的类加载到jvm,并返回对应Class对象
Class employeeClass = Class.forName("com.reflect.entity.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class,String.class,Float.class,String.class
});
Employee employee = (Employee)constructor.newInstance(new Object[]{
100,"张三",5000f,"研发部"
});
//获取当前类所有成员变量
Field[] fields = employeeClass.getDeclaredFields();
for(Field field : fields){
if(field.getModifiers()==1){//public修饰
Object val = field.get(employee);
sout(field.getName()+":"+val);
}else if(field.getModifiers()==2){
String methodName = "get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
Method getMethod = employeeClass.getMethod(methodName);
Object ret= getMethod.invoke(employee);
sout(field.getName()+":"+ret);
}
}
}catch(ClassNotFoundException e){
//类名与类路径书写错误时抛出“类无法找到”异常
e.printStackTrace();
}catch(NoSuchMethodException e){
//没有找到与之对应格式的方法
e.printStackTrace();
}catch(IllegalAccessException e){
//非法访问异常,当在作用域外访问对象方法或成员变量时抛出
e.printStackTrace();
}catch(InstantiationException e){
//对象无法被实例化,抛出“实例化异常”
e.printStackTrace();
}catch(InvocationTargetException e){
//当被调用的方法的内部抛出了异常而没有被捕获时
e.printStackTrace();
}catch(NoSuchFieldException e){
//没有找到对应成员变量时抛出的异常
e.printStackTrace();
}
}
}