是在 运行时 动态访问类与对象的技术
- 在 JDK1.2 版本后的高级特性,隶属于
java.lang.reflect
- 创建对象的实际从编译的时候延迟到程序运行时
- 大多数 Java 框架都基于反射实现参数配置、动态注入等特性
package com.imooc.reflect;
import com.imooc.reflect.entity.Employee;
public class ClassSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.imooc.reflect.entity.Employee");
System.out.println("Employee已被加载到jvm");
Employee emp = (Employee) employeeClass.newInstance() ;
System.out.println(emp);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
- JVM 代表类和接口的类
- Class 对象具体包含了某个特定类的结构信息
- 通过 Class 对象可获取对应类的构造方法/方法/成员变量
方法 | 用途 |
---|
Class.forName() | 静态方法,用于获取指定 Class 对象 |
classObj.newInstance() | 通过默认构造方法创建新的对象 |
classObj.getConstructor() | 获得指定的 public 修饰构造方法 Constructor 对象 |
classObj.getMethod() | 获取指定的 public 修饰方法 Method 对象 |
classObj.getField() | 获取指定的 public 修饰成员变量 Field 对象 |
- 是对 Java 类中的构造方法的抽象
- 包含了具体类的某个具体构造方法的声明
- 通过 Constructor 对象调用带参构造方法创建对象
方法 | 用途 |
---|
classObj.getConstructor() | 获取指定 public 修饰的构造方法对象 |
constructorObj.newInstance() | 通过对应的构造方法创建对象 |
package com.imooc.reflect;
import com.imooc.reflect.entity.Employee;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ConstructorSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.imooc.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,"李磊",3000f,"研发部"
});
System.out.println(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();
}
}
}
- Method 对象代指某个类中的方法的描述
- 通过 Method 对象调用指定对象的对应方法
方法 | 用途 |
---|
classObj.getMethod() | 获取指定 public 修饰的方法对象 |
constructorObj.invoke() | 调用指定对象的对应方法 |
package com.imooc.reflect;
import com.imooc.reflect.entity.Employee;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MethodSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.imooc.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, "李磊", 3000f, "研发部"
});
Method updateSalaryMethod = employeeClass.getMethod("updateSalary", new Class[]{
Float.class
});
Employee employee1 = (Employee) updateSalaryMethod.invoke(employee, new Object[]{1000f});
System.out.println(employee1);
} 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();
}
}
}
方法 | 用途 |
---|
classObj.getField() | 获取指定 public 修饰的成员变量 |
fieldObj.get() | 获取某对象指定成员变量 |
fieldObj.set() | 为某对象指定成员变量赋值 |
package com.imooc.reflect;
import com.imooc.reflect.entity.Employee;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class FieldSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.imooc.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,"李磊",3000f,"研发部"
});
Field enameField = employeeClass.getField("ename");
enameField.set(employee,"李雷");
String ename = (String)enameField.get(employee);
System.out.println("ename:" + ename);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
getDeclaredConstructor(s)|Method(s)|Field(s)
:获取对应对象
getConstructor(s)|Method(s)|Field(s)
只能获取 public
对象getDeclared...
访问非作用域内构造方法、方法、成员变量,会抛出异常
package com.imooc.reflect;
import com.imooc.reflect.entity.Employee;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class getDeclaredSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.imooc.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, "李磊", 3000f, "研发部"
});
Field[] fields = employeeClass.getDeclaredFields();
for (Field field : fields) {
if (field.getModifiers() == 1) {
Object val = field.get(employee);
System.out.println(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);
System.out.println(field.getName() + ":" + ret);
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}