java反射--善用反射等于写活“代码“

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java反射--善用反射等于写活“代码“相关的知识,希望对你有一定的参考价值。


常用api:


 


/**



* 修饰符、父类、实现的接口、注解相关



*/







//获取修饰符,返回值可通过Modifier类进行解读



public native int getModifiers();



//获取父类,如果为Object,父类为null



public native Class<? super T> getSuperclass();



//对于类,为自己声明实现的所有接口,对于接口,为直接扩展的接口,不包括通过父类间接继承来的



public native Class<?>[] getInterfaces();



//自己声明的注解



public Annotation[] getDeclaredAnnotations();



//所有的注解,包括继承得到的



public Annotation[] getAnnotations();



//获取或检查指定类型的注解,包括继承得到的



public <A extends Annotation> A getAnnotation(Class<A> annotationClass);



public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass);







/**



* 内部类相关



*/



//获取所有的public的内部类和接口,包括从父类继承得到的



public Class<?>[] getClasses();



//获取自己声明的所有的内部类和接口



public Class<?>[] getDeclaredClasses();



//如果当前Class为内部类,获取声明该类的最外部的Class对象



public Class<?> getDeclaringClass();



//如果当前Class为内部类,获取直接包含该类的类



public Class<?> getEnclosingClass();



//如果当前Class为本地类或匿名内部类,返回包含它的方法



public Method getEnclosingMethod();







/**



* Class对象类型判断相关



*/



//是否是数组



public native boolean isArray();



//是否是基本类型



public native boolean isPrimitive();



//是否是接口



public native boolean isInterface();



//是否是枚举



public boolean isEnum();



//是否是注解



public boolean isAnnotation();



//是否是匿名内部类



public boolean isAnonymousClass();



//是否是成员类



public boolean isMemberClass();



//是否是本地类



public boolean isLocalClass();

 


JAVA反射原理


什么是反射?



反射,一种计算机处理方式。是程序可以访问、检测和修改它本身状态或行为的一种能力。java反射使得我们可以在程序运行时动态加载一个类,动态获取类的基本信息和定义的方法,构造函数,域等。除了检阅类信息外,还可以动态创建类的实例,执行类实例的方法,获取类实例的域值。反射使java这种静态语言有了动态的特性。



类的加载



java反射机制是围绕Class类展开的,在深入java反射原理之前,需要对类加载机制有一个大致的了解。jvm使用ClassLoader将字节码文件(class文件)加载到方法区内存中:



而java中的Class类对象是可以人工自然性的(也就是说开放的)得到的(虽然你无法像其他类一样运用构造器来得到它的实例,因为



Class对象都是jvm产生的。不过话说回来,客户产生的话也是无意义的),而且,更伟大的是,基于这个基础,java实现了反射机制。



 



获取Class对象有三种方式:



 



1.通过Object类的getClass()方法。例如:



Class c1 = new String("").getClass();



2.通过Class类的静态方法——forName()来实现:



Class c2 = Class.forName("MyObject");



3.如果T是一个已定义的类型的话,在java中,它的.class文件名:T.class就代表了与其匹配的Class对象,例如:



Class c3 = Manager.class;



Class c4 = int.class;



Class c5 = Double[].class;



 



实际运用:( 最近写了一个小东西玩 )注解+反射 自动生成实体类的sql语句(可以批量生成数据库表 或 批量新增表字段 两个功能)



1.第一步:编写自定义注解:



1、元注解(meta-annotation):



 



元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:



    1.@Target,



    2.@Retention,



    3.@Documented,



    4.@Inherited



  这些类型和它们所支持的类在java.lang.annotation包中可以找到。下面我们看一下每个元注解的作用和相应分参数的使用说明。



@Target:



   @Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。



作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)



 取值(ElementType)有:



 



    1.CONSTRUCTOR:用于描述构造器



    2.FIELD:用于描述域



    3.LOCAL_VARIABLE:用于描述局部变量



    4.METHOD:用于描述方法



    5.PACKAGE:用于描述包



    6.PARAMETER:用于描述参数



    7.TYPE:用于描述类、接口(包括注解类型) 或enum声明



@Retention:



 @Retention 定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对 Annotation的“生命周期”限制。



作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)



 取值(RetentionPoicy)有:



 



    1.SOURCE:在源文件中有效(即源文件保留)



    2.CLASS:在class文件中有效(即class保留)



    3.RUNTIME:在运行时有效(即运行时保留)



 




java反射--善用反射等于写活“代码“_程序人生

java反射--善用反射等于写活“代码“_java_02


2.第二步:实体上写上该注解,并利用反射读取(大致思路是读取含义@TableName的自定义注解,绝对生成sql的标签,判断是否创表还是新增,后面根据 自定义注解 @SetTable判断主键,自增,类型,长度,精度,别名,备注等)



java反射--善用反射等于写活“代码“_反射_03



java反射--善用反射等于写活“代码“_反射_04



java反射--善用反射等于写活“代码“_反射_05


 


 

以上是关于java反射--善用反射等于写活“代码“的主要内容,如果未能解决你的问题,请参考以下文章

Java核心技术梳理-类加载机制与反射

漫谈反射

Java高级之注解反射

java反射机制

Java反射的理解-- 通过反射了解集合泛型的本质

反射反射,程序员的快乐