反射
能够分析类能力的程序称为反射
1.Class类
获取Class的三种方式:
-
{@link Object#getClass()}
-
{@link Class#forName(String)}
-
{@code Employee.class }
public void testClass() throws ClassNotFoundException {
Employee employee = new Employee();
Class<? extends Employee> c1 = employee.getClass();
Class<Employee> c2 = Employee.class;
Class<?> c3 = Class.forName("com.java.practice.oop.oop05.Employee");
}
- Class代表一种类型,这种类型不一定是类
public void testType(){
Class<Integer> intClass = int.class;
System.out.println(intClass); // int
}
- newInstance 动态创建类的实例,必须提供无参构造
public void testNewInstance() throws Exception {
Class<?> c = Class.forName("com.java.practice.oop.oop05.Employee");
// 必须提供无参构造
Employee employee = (Employee) c.newInstance();
}
2.反射常用api
- Field
- Method
- Constructor
/**
* 返回名称:
* {@link Field#getName()}
* {@link Method#getName()}
* {@link Constructor#getName()}
*
* 返回Class
* {@link Field#getType()}
*
* 修饰符描述
* {@link Field#getModifiers()}
* {@link Method#getModifiers()}
* {@link Constructor#getModifiers()}
*
* {@link Modifier} 判断修饰符
*/
public void reflectApi() throws Exception {
printClassInfo("java.lang.Double");
}
// 打印某个类的信息 fields constructors methods
public static void printClassInfo(String className) throws Exception {
// print class name and super class name
Class<?> cl = Class.forName(className);
Class<?> superclass = cl.getSuperclass();
String modifiers = Modifier.toString(cl.getModifiers());
if (modifiers.length() > 0)
System.out.print(modifiers + " ");
System.out.print("class " + className);
if (superclass != null && superclass != Object.class)
System.out.print(" extends " + superclass.getName() + " {");
else
System.out.print(" {");
System.out.println();
printFields(cl);
System.out.println();
printConstructor(cl);
System.out.println();
printMethods(cl);
System.out.println("}");
}
private static void printMethods(Class<?> cl) {
Method[] declaredMethods = cl.getDeclaredMethods();
System.out.println("\t// methods");
for (Method c : declaredMethods) {
int modifiers = c.getModifiers();
Class[] parameterTypes = c.getParameterTypes();
StringBuilder params = new StringBuilder();
for (Class p : parameterTypes) {
params.append(p.getName()).append(",");
}
if (params.length() > 0)
params.deleteCharAt(params.length() - 1);
System.out.println("\t" + Modifier.toString(modifiers) + " " + c.getReturnType().getSimpleName() + " " + c.getName() + "(" + params + ")" + ";");
}
}
private static void printConstructor(Class<?> cl) {
Constructor<?>[] constructors = cl.getDeclaredConstructors();
System.out.println("\t// constructors");
for (Constructor c : constructors) {
int modifiers = c.getModifiers();
Class[] parameterTypes = c.getParameterTypes();
StringBuilder params = new StringBuilder();
for (Class p : parameterTypes) {
params.append(p.getName()).append(",");
}
if (params.length() > 0)
params.deleteCharAt(params.length() - 1);
System.out.println("\t" + Modifier.toString(modifiers) + " " + c.getName() + "(" + params + ")" + ";");
}
}
/**
* {@link Class#getDeclaredFields()} 返回的是Field对象数组,记录这个类的全部域
* {@link Class#getFields()} 返回这个类或父类的public
* @param cl
*/
private static void printFields(Class<?> cl) {
Field[] fields = cl.getDeclaredFields();
System.out.println("\t// fields");
for (Field f : fields) {
int modifiers = f.getModifiers();
System.out.println("\t" + Modifier.toString(modifiers) + " " + f.getType().getSimpleName() + " " + f.getName() + ";");
}
}
- 反射分析对象
public void getFieldsValue() throws Exception {
Employee employee = new Employee();
employee.setName("abc");
Class<? extends Employee> c = employee.getClass();
Field name = c.getDeclaredField("name");
name.setAccessible(true); // 私有属性需要设置此属性才能访问
Object res = name.get(employee);
System.out.println(res); // abc
}