java注解使用变量_java注解的使用

时间:2025-04-12 18:39:29

java中注解的使用

1.说再前面

使用注解开发的好处

1.使代码更加干净易读,易于维护修改。比如,以前使用spring的开发,都是基于xml文件实现了统一的配置管理,但是缺点也是显而易见的,就是随着项目的越来越大,xml文件会变得越来越复杂,维护成本也会越来越高。使用注解就可以提供更大的便捷性,易于维护修改。

2 可以实现代码的类型检查,特别是在编译器的角度实现一些类型检查,比如预检查(@Override)和抑制警告(@SuppressWarnings)等。

3 自定义注解,作为额外信息的载体,存储有关程序的额外信息

2 注解的分类以及使用

​ Java注解是附加在代码中的一些元信息,用于编译和运行时进行解析和使用,起到说明、配置的功能。

注解不会影响代码的实际逻辑,仅仅起到辅助性的作用。包含在包中。注解的定义类似于接口的定义,使用@interface来定义,定义一个方法即为注解类型定义了一个元素,方法的声明不允许有参数或throw语句,返回值类型被限定为原始数据类型、字符串String、Class、enums、注解类型,或前面这些的数组,方法可以有默认值。注解并不直接影响代码的语义,但是他可以被看做是程序的工具或者类库。它会反过来对正在运行的程序语义有所影响。注解可以从源文件、class文件或者在运行时通过反射机制多种方式被读取。

一般来说,注解一般分为三种类型: 元注解,标准注解,自定义注解

2.1 元注解

元注解是专职负责注解其他注解,主要是标明该注解的使用范围,生效范围。我们是不能改变它的,只能用它来定义我们自定义的注解。

包括 @Retention @Target @Document @Inherited四种。(中提供,为注释类型)。

注解

说明

@Target

定义注解的作用目标,也就是可以定义注解具体作用在类上,方法上,还是变量上

@Retention

定义注解的保留策略。:注解仅存在于源码中,在class字节码文件中不包含;:默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得;:注解会在class字节码文件中存在,在运行时可以通过反射获取到。

@Document

说明该注解将被包含在javadoc中

@Inherited

说明子类可以继承父类中的该注解

Target类型主要依赖于ElementType这个类型,具体的类型如下:

Target类型

说明

接口、类、枚举、注解

字段、枚举的常量

方法

方法参数

构造函数

ElementType.LOCAL_VARIABLE

局部变量

ElementType.ANNOTATION_TYPE

注解

2.2 标准注解

Java标准注解提供了三个,定义在中的注解,我认为这三个注解的作用更多的是一种注释

@Override 表示当前方法覆盖父类中的方法。

@Deprecated 标记一个元素为已过期,避免使用

支持的元素类型为:CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE

@SuppressWarnings 不输出对应的编译警告

一个简单的使用demo:

@SuppressWarnings(value = {"unused", "rawtypes"})

public class Children extends Parent{

@Override

public void work() {

("我是一个被重写的方法");

}

@Deprecated

public void play(){

("这个方法不推荐使用了");

}

}

2.3 自定义注解实现一个sql语句的拼接

需要注意的方面:注解的定义类似于接口的定义,使用@interface来定义,定义一个方法即为注解类型定义了一个元素,方法的声明不允许有参数或throw语句,返回值类型被限定为原始数据类型、字符串String、Class、enums、注解类型,或前面这些的数组,方法可以有默认值。

自定义注解一般可以分为三步: 定义注解,使用注解,读取注解

定义注解

@Target() //注解加载类上

@Retention() // 运行时读取注解

public @interface Table {

String value();

}

@Target()

@Retention()

public@interface UserFiled {

String name();

String type();

int length();

}

使用注解

// 将自定义的注解加在用户上,实现一个表的映射

@Table(value = "user_table")

public class User {

@UserFiled(name = "user_id",type = "int",length = 8)

private int userId;

@UserFiled(name = "user_name",type = "varchar",length = 16)

private String userName;

@UserFiled(name = "password",type = "varchar",length = 16)

private String password;

public int getUserId() {

return userId;

}

public void setUserId(int userId) {

= userId;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

= userName;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

= password;

}

}

读取注解的内容

/**

* 读取注解中的值

*/

public class GetUser {

public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {

Class userClass = ("");

// 读取类上的注解

Table table = (Table) ();

(());

// 读取属性上注解

Field userId = ("userId");

UserFiled userFiledId = ();

(() + "----" + () + "-----" + ());

Field userName = ("userName");

UserFiled userFiledName = ();

(()+"----"+()+"----"+());

Field password = ("password");

UserFiled userFiledPassword = ();

(() + "-----" + () + "-----" + ());

// 拼接一个sql语句

String name = "chenwei";

String sql ="select * from" + ()+"where"+()+"="+name;

}

}

结果:

user_table

user_id----int-----8

user_name----varchar----16

password-----varchar-----16

自定义注解的实现过程:

1,定义注解

2,使用注解,根据自己定义的注解来达到一些目的,本例中,就是使用注解来完成数据库表和实体类的映射关系

3 读取注解的内容,也是比较重要的一部分,核心还是利用了反射的思想,得到使用注解的这个类,根据类中的getAnnotion的方法得到定义的注解,获得注解上的值。

3 注解的实现的原理

注解的实现的原理很大的一部分是基于反射实现。

​ 反射可以获取到Class对象,进而获取到Constructor、Field、Method等实例,点开源码结构发现Class、Constructor、Field、Method等均实现了AnnotatedElement接口,AnnotatedElement接口的方法如下

// 判断该元素是否包含指定注解,包含则返回true

boolean isAnnotationPresent(Class extends Annotation> annotationClass)

// 返回该元素上对应的注解,如果没有返回null

T getAnnotation(Class annotationClass);

// 返回该元素上的所有注解,如果没有任何注解则返回一个空数组

Annotation[] getAnnotations();

// 返回指定类型的注解,如果没有返回空数组

T[] getAnnotationsByType(Class annotationClass)

// 返回指定类型的注解,如果没有返回空数组,只包含直接标注的注解,不包含inherited的注解

T getDeclaredAnnotation(Class annotationClass)

// 返回指定类型的注解,如果没有返回空数组,只包含直接标注的注解,不包含inherited的注解

T[] getDeclaredAnnotationsByType

// 返回该元素上的所有注解,如果没有任何注解则返回一个空数组,只包含直接标注的注解,不包含inherited的注解

Annotation[] getDeclaredAnnotations();

通过一个实例再次说明一下注解的使用过程:

定义注解

@Documented

@Target({, ,})

@Retention()

public @interface MyAnnotaion {

String getValue() default "this is myAnntaion";

int order() default 0;

}

使用注解

@MyAnnotaion(getValue = "annotation on class")

public class Demo {

@MyAnnotaion(getValue = "annotation on filed")

public String name;

@MyAnnotaion(getValue = "annotation on method")

public void hello(){

}

@MyAnnotaion

public void defaultMethod(){

}

}

利用反射读取注解中的值。

public class TestDemo {

public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {

/**

* 获取类上的注解

*/

Class demoClass = ;

Annotation[] annotaion = ();

printAnnotation(annotaion);

/**

* 读取成员变量上的注解

*/

Field name = ("name");

Annotation[] getOnFiled = ();

printAnnotation(getOnFiled);

/**

* 读取方法上的注解

*/

Method hello = ("hello", null);

MyAnnotaion onMethod = ();

(());

/**

* 获取默认方法上的注解

*/

Method defaultMethod = ("defaultMethod", null);

MyAnnotaion onDefaultMethod = ();

(());

}

public static void printAnnotation(Annotation... annotations) {

for (Annotation annotation : annotations) {

(annotation);

}

}

}

运行结果

@(getValue=annotation on class, order=0)

@(getValue=annotation on filed, order=0)

annotation on method

this is myAnntaion

参考资料:

《java编程思想》