反射:程序运行时动态的访问类或者对象,如下述程序中根据className的不同,程序运行时动态的加载类和创建对象。
大部分的高级框架都用到反射技术,如spring容器启动后,会自动通过各类注解(@Resource、@Service等)实例化对象。
反射用到核心类有:Class、Constructor、Method、Field,下述的示例演示了这些类的核心方法。
package com.ng.web.test;
public class Student {
private String num;//学号
private String name;
private int age;
static {
System.out.println("加载Student类时执行");//Class.forName(className) 执行
}
@Override
public String toString() {
return this.hashCode() + "-Student{" +
"num='" + num + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
public Student() {
}
public Student(String num, String name, int age) {
this.num = num;
this.name = name;
this.age = age;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.ng.web.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
try {
String className = "com.ng.web.test.Student";
Class studentClass = Class.forName(className);//执行完此行代码,输出Student类的静态代码块的内容:加载Student类时执行
//实例化,调用默认构造方法
Student student = (Student) studentClass.newInstance();
System.out.println("默认构造函数构造的对象:" + student);//默认构造函数构造的对象2096057945-Student{num='null', name='null', age=0}
//带参数构造方法
Constructor constructor = studentClass.getConstructor(new Class[]{String.class, String.class, int.class});
student = (Student) constructor.newInstance("001", "张三", 18);
System.out.println("带参构造函数构造的对象:" + student);//带参构造函数构造的对象1689843956-Student{num='001', name='张三', age=18}
//方法类
Method setAgeMethod = studentClass.getMethod("setAge", int.class);
setAgeMethod.invoke(student,20);
System.out.println("修改年龄后:" + student);//修改年龄后:1689843956-Student{num='001', name='张三', age=20}
//字段属性类
Field nameFiled = studentClass.getDeclaredField("name");
String nameValue = "";
if(nameFiled.getModifiers() == 1) { //public 属性
nameValue = (String)nameFiled.get(student);
}else if(nameFiled.getModifiers() == 2) { //private 属性
Method getNameMethod = studentClass.getMethod("get" + nameFiled.getName().substring(0, 1).toUpperCase() +
nameFiled.getName().substring(1));
nameValue = (String)getNameMethod.invoke(student);
}
System.out.println("属性名name值:" + nameValue);//属性名name值:张三
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}