第一章:前言

在项目中不时会用到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

 

posted on 2018-01-09 23:57  Stark_Tan  阅读(187)  评论(0编辑  收藏  举报