第一章:前言
在项目中不时会用到Java的反射技术,但是一直没有时间进行一次总结,这次就把自己想到的Java反射系统的学习一下。
Java反射主要用来在程序运行时,动态获取类的一些属性,我把我想到的可以用反射获取的数据列一下,然后进行Demo。
Java类:类名,父类名,接口名,父类/接口泛型类型,注解。
方法:自身方法,父类方法,接口方法,注解,参数类型,参数注解
属性:自身属性,父类属性,属性修改,注解
第二章:实现
第一步:准备接口、父类、注解类、泛型、目标类
/**
* 类和接口的注解
*/
@Target(value =
{ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
//@Inherited 被子类继承
public @interface
Anno
{
public String name();
}
|
/**
* 接口
*/
@Anno(name = "Interface")
public interface IBase<T> {
default void callI(Date date) {
System.out.println("I am Interface! " + date);
}
}
|
/**
* Created by Stark on 2018/1/8.
* 父类
*/
@Anno(name = "SupClass")
public class SupBase<T extends Object> {
private String nameSupPri = "SupClass Private Property";
public String nameSupPub = "SupClass Public Property";
private void callSupPri(Date date) {
System.out.println("I am SupBase Private " + date);
}
public void callSupPub(Date date) {
System.out.println("I am SupBase Public " + date);
}
}
|
第二步:创建目标类
/**
* 目标类
*/
@Anno(name = "Target Class")
public class Base extends SupBase<String> implements IBase<Object> {
@Anno(name = "callPri")
private void callPri(@Anno(name = "param date") Date date) {
System.out.println("I am SubObject Private " + date);
}
public void callPub(Date date) {
System.out.println("I am SubObject Public" + date);
}
@Anno(name="filed base")
private String namePri = "Class Private Property";
public String namePub = "Class Public Property";
}
|
第三章:测试
第一步:获取类、接口的属性
Base base = new Base();
Class<? extends Base> baseclass = base.getClass();
Class<?> superclass = baseclass.getSuperclass();
Class<?>[] interfaces = baseclass.getInterfaces();
Class tclass = (Class) ((ParameterizedType) baseclass.getGenericSuperclass())
.getActualTypeArguments()[0];
Class oclass = (Class) ((ParameterizedType) baseclass.getGenericInterfaces()[0])
.getActualTypeArguments()[0];
//获取 类名,父类名,接口名,泛型类型,注解
System.out.println("class name-->" + baseclass.getSimpleName());
System.out.println("supclass name-->" + superclass.getSimpleName());
System.out.println("interface name-->" + interfaces[0].getSimpleName());
System.out.println("supclass t name-->" + tclass.getSimpleName());
System.out.println("interface t name-->" + oclass.getSimpleName());
Anno baseanno = baseclass.getAnnotation(Anno.class);
Anno superclassanno = superclass.getAnnotation(Anno.class);
Anno interfacesanno = interfaces[0].getAnnotation(Anno.class);
//都成了代理类 注解类的信息包含在里面
//System.out.println("Annotation name---->"+baseanno.getClass().getSimpleName());
//可以获取参数
System.out.println("class Annotation Value---->" + baseanno.name());
System.out.println("supclass Annotation Value---->" + superclassanno.name());
System.out.println("interface Annotation Value---->" + interfacesanno.name());
|
第二步:获取方法信息,执行方法
//获取方法:自身方法,父类方法,接口方法,注解,参数类型,参数注解
Method[] methods = baseclass.getDeclaredMethods(); //getMethods() 会获得所有public方法
for (Method method : methods) {
method.setAccessible(true);//这样就可以访问私有方法了
System.out.println(method.getName());
//获取方法参数
Type[] paramTypes = method.getGenericParameterTypes();
System.out.println(paramTypes[0].getTypeName());
method.invoke(base, new Date());
}
methods = superclass.getDeclaredMethods(); //getMethods() 会获得所有public方法
for (Method method : methods) {
method.setAccessible(true);//这样就可以访问私有方法了
System.out.println(method.getName());
method.invoke(base, new Date());
}
methods = interfaces[0].getDeclaredMethods(); //getMethods() 会获得所有public方法
for (Method method : methods) {
System.out.println(method.getName());
method.invoke(base, new Date());
}
Method method = baseclass.getDeclaredMethod("callPri", Date.class);
method.setAccessible(true);
//获取详细的方法注解
Annotation[] annos = method.getDeclaredAnnotations();
System.out.println(((Anno) annos[0]).name());
//获取方法参数注解
Anno anno = (Anno) method.getParameterAnnotations()[0][0];
System.out.println(anno.name());
|
第三步:获取属性信息,修改属性值
//属性:自身属性,父类属性,属性修改,注解
Field[] fields = baseclass.getDeclaredFields();
for(Field field:fields){
field.setAccessible(true);
System.out.println(field.getName());
System.out.println(field.get(base));
}
fields = superclass.getDeclaredFields();
for(Field field:fields){
field.setAccessible(true);
System.out.println(field.getName());
System.out.println(field.get(base));
}
Field field = baseclass.getDeclaredField("namePri");
field.setAccessible(true);
Object orig = field.get(base);
field.set(base,orig+" change");
System.out.println(field.get(base));
anno = (Anno) field.getDeclaredAnnotations()[0];
System.out.println(anno.name());
|
第四步:全部测试结果
class name-->Base
supclass name-->SupBase
interface name-->IBase
supclass t name-->String
interface t name-->Object
class Annotation Value---->Target Class
supclass Annotation Value---->SupClass
interface Annotation Value---->Interface
callPri
java.util.Date
I am SubObject Private Tue Jan 09 10:59:22 GMT+08:00 2018
callPub
java.util.Date
I am SubObject PublicTue Jan 09 10:59:22 GMT+08:00 2018
callSupPub
I am SupBase Public Tue Jan 09 10:59:22 GMT+08:00 2018
callSupPri
I am SupBase Private Tue Jan 09 10:59:22 GMT+08:00 2018
callI
I am Interface! Tue Jan 09 10:59:22 GMT+08:00 2018
callPri
param date
namePri
Class Private Property
namePub
Class Public Property
nameSupPri
SupClass Private Property
nameSupPub
SupClass Public Property
Class Private Property change
filed base
|