java注解

java注解

注解如同标签

注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释的代码本身的一部分。注解对于代码的运行效果没有直接影响。

**注解就是对于代码中某些鲜活个体的贴上去的一张标签。简化来讲,注解如同一张标签** 注解通过 @interface 关键字进行定义
1
2
public @interface TestAnnotation {
}

使用注解

1
2
3
4
public @interface TestAnnotation {
@TestAnnotation
public class Test {
}

可以理解为将 TestAnnotation 这张标签贴到 Test 这个类上面。

元注解

元注解是一种基本注解,是可以注解到注解上的注解。元注解也是一张标签,但是它是一张特殊的标签,它的作用和目的就是给其他普通的标签进行解释说明的。

元标签有 @Retention、@Documented、@Target、@Inherited、@Repeatable 5 种。

@Retention

Retention 的英文意为保留期的意思。当 @Retention 应用到一个注解上的时候,它解释说明了这个注解的的存活时间。

  • RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
  • RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
  • RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。

@Documented

作用是能够将注解中的元素包含到 Javadoc 中去。可有可无。

@Target

当一个注解被 @Target 注解时,这个注解就被限定了运用的场景。

  • ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
  • ElementType.CONSTRUCTOR 可以给构造方法进行注解
  • ElementType.FIELD 可以给属性进行注解
  • ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
  • ElementType.METHOD 可以给方法进行注解
  • ElementType.PACKAGE 可以给一个包进行注解
  • ElementType.PARAMETER 可以给一个方法内的参数进行注解
  • ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举

@Inherited

Inherited 是继承的意思,子类继承超类的注解。

1
2
3
4
5
6
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Test {}
@Test
public class A {}
public class B extends A {}

注解 Test 被 @Inherited 修饰,之后类 A 被 Test 注解,类 B 继承 A,类 B 也拥有 Test 这个注解。

@Repeatable

Repeatable是可重复的意思。通常是注解的值可以同时取多个。相当于可以取多个标签。

注解的属性

  • 注解的属性也叫做成员变量。注解只有成员变量,没有方法。注解的成员变量在注解的定义中以“无形参的方法”形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型。
1
2
3
4
5
6
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
int id();
String msg();
}

TestAnnotation 这个注解中拥有 id 和 msg 两个属性。

  • 在使用的时候,我们应该给它们进行赋值。赋值的方式是在注解的括号内以 value=”” 形式,多个属性之前用,隔开。
1
2
3
@TestAnnotation(id=3,msg="hello annotation")
public class Test {
}
  • 注解中属性可以有默认值,默认值需要用 default 关键值指定。
1
2
3
4
5
6
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
public int id() default -1;
public String msg() default "Hi";
}

TestAnnotation 中 id 属性默认值为 -1,msg 属性默认值为 Hi。

  • 如果一个注解内仅仅只有一个名字为 value 的属性时,应用这个注解时可以直接接属性值填写到括号内。
1
2
3
public @interface Check {
String value();
}
1
2
@Check("hi")
int a;

这和下面的效果是一样的

1
2
@Check(value="hi")
int a;
  • 一个注解没有任何属性,那么在应用这个注解的时候,括号都可以省略。
1
public @interface Perform {}
1
2
@Perform
public void testMethod(){}

Java 预置的注解

@Deprecated

用来标记过时的元素。

1
2
3
4
5
6
7
8
9
public class Hero {
@Deprecated
public void say(){
System.out.println("Noting has to say!");
}
public void speak(){
System.out.println("I have a dream!");
}
}

定义了一个 Hero 类,它有两个方法 say() 和 speak() ,其中 say() 被 @Deprecated 注解。然后我们分别调用它们。

可以看到,say() 方法上面被划了一条直线,这就是编译器识别后的提醒效果。

@Override

提示子类要复写父类中被 @Override 修饰的方法。

@SuppressWarnings

阻止警告。

1
2
3
4
5
6
@SuppressWarnings("deprecation")
public void test1(){
Hero hero = new Hero();
hero.say();
hero.speak();
}

@SuppressWarnings(“deprecation”)会阻止调用过时元素警告。

注解与反射

注解通过反射获取

通过 getAnnotation() 或者getAnnotations() 方法来获取 Annotation 对象。

1
2
//返回指定A类型的注解
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {}
1
2
//返回注解到这个元素上的所有注解
public Annotation[] getAnnotations() {}

java注解

作者

lvjie

发布于

2022-06-18

许可协议


:D 一言句子获取中...