反射
Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
引用加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,反射由此而来
正常方式:引入需要的包类名称—》new实例化—》取得实例化对象
反射方式:实例化对象—》getClass()方法—》得到完整的包类名称和结构
Class类:描述类的类,本身也是一个类
public class Test
{
//Class类的创建方式
public static void main( String[] args ) throws ClassNotFoundException {
People people = new People();
// 通过对象获得
Class c1 = people.getClass();
// 通过forName获得
Class c2 = Class.forName("com.pang.People");
// 通过类名.class获得
Class c3 = People.class;
}
}
类加载内存分析
- 加载
- 链接
- 初始化
获取类的运行时结构
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
Peo peo = new Peo();
Class c1 = peo.getClass();
// 获取类的名字
System.out.println(c1.getName()); // 包名+类名
System.out.println(c1.getSimpleName());// 类名
// 获取类的属性
Field[] fields = c1.getFields(); //只能获取Public属性
fields = c1.getDeclaredFields();// 能获取全部属性
for (Field field:fields){
System.out.println(field);
}
// 获取类的方法
Method[] methods = c1.getMethods(); // 获取public方法(包括父类)
for(Method method:methods){
System.out.println("getMethods():" + method);
}
methods = c1.getDeclaredMethods(); // 获取本类的全部方法
for(Method method:methods){
System.out.println("getDeclaredMethods()" + method);
}
// 获取类的构造器
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
}
}
通过反射创建对象
// newInstance调用无参构造方法创建对象,要强转为People类(创建的是一个Object类)
People peo1 = (People) c1.newInstance();
通过反射调用方法(代理模式原理)
// setId是people类的方法名,String.class是该方法的参数类型
Method method = c1.getMethod("setId",String.class);
// peo1是实例对象,100是你要设置的方法参数
method.invoke(peo1,"100");
这样就通过反射完成了创建对象和属性的注入
通过反射获取类上的注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation a:annotations) {
System.out.println(a);
}
通过反射获取方法上的注解
// a是方法名,后面是参数类的类信息
Method method = c1.getDeclaredMethod("a", String.class);
// RequestMapping.class,想要的注解类的类信息
System.out.println(method.getAnnotation(RequestMapping.class));
获得注解的值
Method method=c1.getDeclaredMethod("a",String.class,Integer.class);
RequestMapping annotation = method.getAnnotation(RequestMapping.class);
System.out.println(annotation.value());
获取注解的值就是注解变量+.+注解参数(),如果注解是@RequestMapping(id=“createOrder”),那么通过annotation.id()获取id的值