前言:
反射机制在一般业务代码开发中用到的不多,平时接触的也比较少,但是经常使用到的开发工具、框架的源码中,反射机制出现的却十分频繁,比如spring框架的核心IOC控制反转就是基于Java的反射实现的。所以,对于想看懂源码,掌握反射机制是必不可少的。
反射常用API
1. 通过反射获取对象的方法
1.1.知道要加载的类的路径名时,直接使用Class.forName(“xxx”):
T t= Class.forName("com.sun.sboot.model.Student");
1.2.当知道需要获取的类时:
Class clazz = Student.class;
1.3.当需要获取的类已存在时:
Student student = new Student();
Class clazz = student.getClass();
**
2.通过反射生成的clazz创建对象:
**
2.1.直接创建
T t= (T)clazz.newInstance();
这种方式是最简单的,但是有个弊端:该方法只能调用无参构造器来创建对象。
2.2.借助Constructor
创建无参构造器并创建对象
Constructor constructor = clazz.getConstructor();
Tt= (T)constructor.newInstance();
创建有参构造器创建对象
Constructor constructor = clazz.getConstructor(float.class, int.class, String[].class);
T t = (T)constructor.newInstance(1234.5f, 5, new String[]{"sport","reading"});
3.获取Class的Method:
3.1.获取某个public方法并执行
Method eat = clazz.getMethod("eat", String.class, Float.class);
eat.invoke(t,"chicken",125.8f);
String.class、Float.class:为有调的方法的参数类型,可以有多个(基本类型就直接写double.class、int.class等);
invoke中 “t”为被调用的对象,另外两个为方法执行的参数,需和getMethod中定义的一一对应。
3.2.获取Classd对象某个private方法并执行
Method reading=clazz.getDeclaredMethod("reading", Book.class);
reading.setAccessible(true);//取消method的权限控制检查
String str = (String) reading.invoke(t,new Book("Jane Eyre","romantic"));
setAccessible(true)设置method的权限控制检查,为true为取消权限检查,默认为false。
4.注解相关
现如今的java开发中,注解机制因其使用方便、侵入性低、且不会影响业务代码等优点,已成为举足轻重的地步,现在主流的开发框架如:spring全家桶、mybatis等都提供了自己封装的注解。注解的定义很简单,@Interface,再使用元注解标明生命周期、使用位置等,此处不多做说明。
注解的解析使用到了java的反射机制。
4.1.获取一个class中所有的注解
先定义一个类,并添加注解:
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.util.Arrays;
@Component(value = "student")
@Service
public class Student extends Person{
private float score;
public int rank;
private String[] likes;
...
}
可以看到,该类用到了@Component和@Service,下面使用Class的getAnnotations()获取注解类型
//1.返回该类上所有注解
Annotation[] annotations = clazz.getAnnotations();
for(Annotation annot : annotations){
System.out.println("注释的注释类型:"+annot.annotationType());
}
执行结果如图
4.2.获取某个特定注解,并获取该注解的value
获取特定注解
Annotation component = clazz.getAnnotation(Component.class);
System.out.println(component.toString());
执行结果为
获取注解的属性
Component component1 =(Component) clazz.getAnnotation(Component.class);
System.out.println(component1.value());
4.3.获取Method上的注解
定义一个method
@Override
@PostConstruct
@Bean(value="eattt")
public void eat(String food, Float weight) {
System.out.println(" The student is eating "+food+" and "+ weight +" !!");
}
Method method = clazz.getMethod("eat",String.class, Float.class);
Annotation[] methodAnn = method.getDeclaredAnnotations();
for (Annotation ann : methodAnn) {
System.out.println(ann.annotationType());
}
执行结果如图:
其他的如method.getDeclaredAnnotations()及获取注解value等值得方法等,在此就不赘述了,需要的同学可自行查阅java api。
结语:
以上内容都是我个人的理解,如有不到之处,还望指正,共同学习。
**源码下载地址:**https://download.csdn.net/download/fangliang924/11918508