java ----> 注解/反射

注解

一个例子,摘自Junit-4.12.jar源码。

1 @Retention(RetentionPolicy.RUNTIME)
2 @Target({java.lang.annotation.ElementType.METHOD})
3 public @interface Test{
4
5   //......
6 }

关注两个元注解和两个类,它们位于java.lang.annotation包中。

@Retention(RetentionPolicy.RUNTIME)
@Target(java.lang.annotation.ElementType.METHOD)

1、@Retention和RetentionPolicy

@Retention

表示要保留带注释类型的注释的时间长度。可以理解为注解的生命周期。 如果注释类型声明中不存在Retention注释,则保留策略默认为RetentionPolicy.CLASS。

RetensionPolicy

注释保留策略。RetensionPolicy是一个枚举类型的类。 此枚举类型的常量描述了用于保留注释的各种策略。 它们与Retention元注释类型结合使用,以指定保留注释的时间。有三个枚举类型的常量,分别是SOURCE,CLASS,RUNTIME。它们分别对应java源文件阶段,class文件阶段,内存中的字节码阶段。(参考博客:https://www.cnblogs.com/xdp-gacl/p/3622275.html

SOURCE:表示编译器会丢弃注解。

CLASS:这是默认的保留策略。表示编译器会在类文件中记录注解,但是在运行时VM不会保留注解。

RUNTIME:表示编译器会在类文件中记录注解,并且在运行时VM会保留注解。可以通过反射技术读取注解。

2、@Target和ElementType

@Target

表示注释类型可用的上下文环境。

ElementType

元素类型。ElementType是一个枚举类型的类。描述了注解在java编程中可能出现的语法位置。 它们与Target元注释类型结合使用,以指定给定类型的注解的合法位置。有10个枚举类型的常量,分别是TYPE、FIELD、METHOD、PARAMETER、CONSTRUCTOR、LOCAL_VARIABLE、ANNOTATION_TYPE、PACKAGE、TYPE_PARAMETER、TYPE_USE

TYPE:类,接口(包括注解),枚举声明

FIELD:字段(包括枚举的常量)声明

METHOD:方法声明

PARAMETER:格式化参数声明

CONSTRUCTOR:构造器声明

LOCAL_VARIABLE:局部变量声明

ANNOTATION_TYPE:注解类型声明

PACKAGE:包声明

定义一个注解

1 public @interface FirstAnnotation{}

注解的本质

注解是一个特殊的类,更像是一个接口。

注解和反射的关系

说明:ClassName表示某个类的名称;AnnotationName表示某个注解的名称。

通过反射技术可以获取注解的信息。

获取注解:Method#getAnnotation(AnnotationName.class)

或者:ClassName.class.getAnnotation(AnnotationName.class)

检查注解是否存在:ClassName.class.isAnnotationPresent(AnnotationName.class)

反射

1、反射:在运行状态中,动态获取对象的信息或者动态调用对象的方法的技术。

2、RTTI(run-time type identification),运行时类型识别,在运行时识别一个对象的类型和类的信息。两种方式:编译期已经知道所有类型;通过反射机制在运行时获取类型的信息。

3、Class:java中获取运行时类型信息的类。

Class对象的作用:为Java虚拟机(JVM)创建实例对象或者提供静态变量的引用值的媒介。Class对象由类加载器子系统加载到JVM中。Class对象是被按需加载的。

获取Class对象的方式:

1)、Class.forName("...")

2)、ClassName.class,不会触发类的初始化

3)、obj.getClass()

4、类的加载过程:

加载 -> 链接(验证->准备->解析)->初始化

加载:已加载字节码文件,可通过它创建Class对象

链接:

验证:安全性和完整性

准备:为静态变量分配空间

解析:处理类中的其他所有引用

初始化:对超类初始化和静态变量,静态代码块等初始化。

5、关注一个类和一个类库:

java.lang.Class

方法:

forName("指定类的全限定名") // 获取Class对象的引用

newInstance() // 实例化默认构造方法

①构造方法

getConstructor(指定参数类型,一个或者多个) // 获得指定参数类型的public构造方法,只有一个

getConstructors() // 获得所有public构造方法

getDeclaredConstructor(指定参数类型,一个或者多个) // 获得指定参数类型的构造方法(包括private),只有一个

getDeclaredConstructors() // 获得全部的构造方法(包括private),返回数组

②属性

getField("指定属性名称") // 获得指定名称 的public属性,属性必须存在

getField() // 获得所有public属性,包括父类,属性必须存在

getDeclaredField("指定属性名称") // 获得指定名称的属性(包括private),不包含父类的属性

getDeclaredField() //获得所有声明的属性(包括private),返回数组,不包含父类的属性

③方法

getMethod("指定方法名称",指定参数类型) // 获得指定方法名称和参数类型的public方法

getMethods() // 获得所有public方法

getDeclaredMethod("指定方法名称") //获得指定方法名称的方法(包括private),不包含父类的方法

getDeclaredMethods() // 获得所有声明的方法(包括private),返回数组,不包含父类的方法

java.lang.reflect类库,类库中常用的几个类:Constructor,Field,Method。

①Constructor

getParameterTypes() // 获得构造方法参数类型,返回Class类型数组

getDeclaringClass() //返回Class对象,可以用过Class.getName()获得类的全限定名

getGenericParameterTypes() // 获得构造方法的形参类型,返回Type类型数组。

newInstance(Object... initargs) // 通过构造方法创建实例

②Field

setAccessible(true) // 设置该private属性可以被访问到,false表示该属性不可被访问到

getType() // 返回该属性声明的类型

getName() // 返回指定field的名字

get(Object obj) // 返回指定field的值

set(Object obj, object value) // 重新设置指定field的值

③Method

setAccessible(true) //设置该private方法可被访问,false表示该方法不可被访问到

invoke(Object obj,Object... args) // 调用指定方法名和参数的方法

getReturnType() // 获得方法的返回类型

getName() // 获得方法名称

参考:《jdk1.8.0_172-src》《jdk1.8.0_172-docs-all》

原文地址:https://www.cnblogs.com/mrray1105/p/9664303.html

时间: 2024-11-05 15:57:47

java ----> 注解/反射的相关文章

Java注解教程:自定义注解示例,利用反射进行解析

Java注解能够提供代码的相关信息,同时对于所注解的代码结构又没有直接影响.在这篇教程中,我们将学习Java注解,如何编写自定义注解,注解的使用,以及如何使用反射解析注解. 注解是Java 1.5引入的,目前已被广泛应用于各种Java框架,如Hibernate,Jersey,Spring.注解相当于是一种嵌入在程序中的元数据,可以使用注解解析工具或编译器对其进行解析,也可以指定注解在编译期或运行期有效. 在注解诞生之前,程序的元数据存在的形式仅限于java注释或javadoc,但注解可以提供更多

Java注解(2)-注解处理器(运行时|RetentionPolicy.RUNTIME)

如果没有用来读取注解的工具,那注解将基本没有任何作用,它也不会比注释更有用.读取注解的工具叫作注解处理器.Java提供了两种方式来处理注解:第一种是利用运行时反射机制:另一种是使用Java提供的API来处理编译期的注解. 反射机制方式的注解处理器 仅当定义的注解的@Retention为RUNTIME时,才能够通过运行时的反射机制来处理注解.下面结合例子来说明这种方式的处理方法. Java中的反射API(如java.lang.Class.java.lang.reflect.Field等)都实现了接

Java注解(3)-注解处理器(编译期|RetentionPolicy.SOURCE)

注解的处理除了可以在运行时通过反射机制处理外,还可以在编译期进行处理.在编译期处理注解时,会处理到不再产生新的源文件为止,之后再对所有源文件进行编译. Java5中提供了apt工具来进行编译期的注解处理.apt是命令行工具,与之配套的是一套描述"程序在编译时刻的静态结构"的API:Mirror API(com.sun.mirror.*).通过Mirror API可以获取到被注解的Java类型元素的信息,从而提供自定义的处理逻辑.具体的处理工具交给apt来处理.编写注解处理器的核心是两个

java注解中的元注解

一:java注解中的元注解 四个元注解分别是:@Target,@Retention,@Documented,@Inherited , 再次强调下元注解是java API提供,是专门用来定义注解的注解,其作用分别如下: @Target 表示该注解用于什么地方,可能的值在枚举类 ElemenetType 中,包括: ElemenetType.CONSTRUCTOR----------------------------构造器声明 ElemenetType.FIELD ----------------

Java 注解

Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和着任何元数据(metadata)的途径和方法.Annotion(注解)是一个接口,程序可以通过反射来获取指定程序元素的Annotion对象,然后通过Annotion对象来获取注解里面的元数据. Annotation能被用来为某个程序元素(类.方法.成员变量等)关联任何的信息.需要注意的是,这里存在着一个基本的规则:Annotation不能影响程序代码的执行,无论增加.删除 Annotation,代码都始终如一的执行.另

Java注解项目实战即模拟Hibenernate生成sql语句

整理了近期学习java注解的部分代码 ,借助java注解模拟Hibenernate ORM模型建立对象与sql语句的映射 Table 注解的创建 package com.imooc.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.

使用Java注解开发自动生成SQL

使用注解开发的好处就是减少配置文件的使用.在实际过程中,随着项目越来越复杂,功能越来越多,会产生非常多的配置文件.但是,当配置文件过多,实际维护过程中产生的问题就不容易定位,这样就会徒劳的增加工作量.而使用注解开发,可以减少配置文件的使用,方便代码的维护,同时,在开发速度上也有大幅提升,因此,学会使用注解开发,是有必要掌握的一项技能. 下面为各位展示下使用注解开发自动生成SQL语句的过程. 首先先定义一个实体类,用于和数据库字段进行映射,为了方便,数据库字段名称和实体类变量名称保持一致. pac

Java:反射

初识Java反射机制: 从上面的描述可以看出Java的反射机制使得Java语言可以在运行时去认识在编译时并不了解的类/对象的信息,并且能够调用相应的方法或修改属性的值.Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的内部信息(包括其modifiers(如public, static等).superclass(如Object).interfaces(如Serializable),也包括fields和methods的所有信息),动态地生

java注解例子

java注解在web框架中使用比较广泛,这使得对象之间的关系配置起来更加容易 目前web框架中最常用的两种配置对象依赖关系的方式就是注解和xml配置文件的方法,api配置相对来说用的少一些, 下面实现一个Table注解来实现数据库表和实体bean之间的对应关系,实现一个Column注解来实现数据库表中每个字段和实体bean每个属性之间的 对应关系.java中的orm基本上就是根据这种思想来实现的. Table注解代码: package com.panther.dong.annotation.an