logo头像

不破不立

Java注解以及自定义注解

Java注解想必很多人都见到过,这里就带大家来了解一下Java的几个常用注解的意思以及Java元注解和自定义注解的实现。

内容大纲  

  Java注解  
    @Override   
    @Deprecated   
    @SuppressWarnings   
  元注解  
    @Target  
    @Target  
    @Retention  
    @Inherited  
    @Documented  
  自定义注解  
    语法要求  
  解析注解  
    自定义注解 @Description  
    使用自定义注解 @Description   
    通过反射进行注解解析  


Java注解

@Override

  重写注解:一般用于方法上,表示该方法重写父类或者接口的方法。
  如父类Person:

1
2
3
4
5
public class Person {
void eat(){
System.out.println("eat anything");
}
}

  子类Child重写eat方法需要使用到@Override注解:

1
2
3
4
5
6
public class Child extends Person {
@Override
public void eat() {
System.out.println("eat something");
}
}

@Deprecated

  废弃注解:可以用于类、方法、成员变量上,表示该类、方法、成员变量已经被废弃,不建议使用
  父类Person原来有个look方法:

1
2
3
void look(){
System.out.println("look");
}

  但是开发后期发现这个方法不合理,如有些人天生看不见,但是又不能删除,因为可能有些地方已经用到了这个方法;故需要将其标志为废弃方法,不建议使用,加@Deprecated注解,变成:

1
2
3
4
@Deprecated
void look(){
System.out.println("look");
}

@SuppressWarnings

  忽略废弃注解:用于应对需要使用被@Deprecated标识的类、方法、成员变量时,忽略如test 标识的情况。
  当在某些情况下需要用到Person类的look方法时,发现它已经被标识为已废弃,此时调用该方法就会出现在调用处方法名会有删除线,表示不建议使用,这里就需要用到@SuppressWarnings(“deprecation”),即在此处消除已废弃的定义

1
2
3
4
5
@SuppressWarnings("deprecation")//消除look方法被@Deprecated注解定义后
public void test(){
Person p = new Child();
p.look();
}

1
2
3
4
5
6
7
8
9
10
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description{

String desc();
String author();
int age() default 18;
}

元注解

  元注解,即用于定义注解的注解。

1
2
3
4
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented

@Target

  作用域:构造函数,字段,局部变量,方法,包,参数,类,接口

@Retention

  生命周期:源码,编译时,运行时

@Inherited

  (标识注解)允许子类继承

@Documented

  javadoc

自定义注解

语法要求

  1. 使用@interface关键字定义注解;
  2. 成员变量必须以无参数无异常方式声明;
  3. 可以用default给成员指定默认值;
  4. 成员类型是受限的,合法的类型包括原始类型(即int,double等等)及String,Class,Annotation,Enumeration;
  5. 如果注解只有一个成员,则成员名约定取名为value(),在使用时可以忽略成员名和赋值号(=);
  6. 注解类可以没有成员,没有成员的注解称为标识注解。
1
2
3
4
5
6
public @interface Description{

String desc();
String author();
int age() default 18;
}

解析注解

自定义注解 @Description

  首先定义一个简单自定义注解 @Description 如下:

1
2
3
4
5
6
7
8
9
10
import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description{

String value();
}

使用自定义注解 @Description

  在Child的类名上添加 @Description("I am a class(Child) annotation")
  在Child的方法名上添加 @Description("I am a method (eat) annotation")

通过反射进行注解解析

  新建一个ParseDescription类,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.lang.reflect.Method;
import java.util.logging.Logger;

public class ParseDescription {

private static Logger logger = Logger.getLogger("com.panhainan.annotation.ParseDescription");
public static void main(String[] args) {
try {
//解析注解
//1.使用类加载器加载类
Class c = Class.forName("com.panhainan.annotation.Child");
//2.找到类上的注解
boolean istExist = c.isAnnotationPresent(Description.class);
if(istExist){
//3.拿到注解实例
Description d = (Description) c.getAnnotation(Description.class);
logger.info(d.value());
}
//4.找到方法上的注解
Method[] methods = c.getMethods();
for (Method method : methods){
if(method.isAnnotationPresent(Description.class)){
Description md = (Description)method.getAnnotation(Description.class);
logger.info(md.value());
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}

  运行可以得到如下结果:

1
2
3
4
三月 22, 2018 11:51:53 上午 com.panhainan.annotation.ParseDescription main
信息: I am a class(Child) annotation
三月 22, 2018 11:51:53 上午 com.panhainan.annotation.ParseDescription main
信息: I am a method (eat) annotation

  读者可以一一尝试@Target、@Retention、@Inherited、@Documented的不同的定义法,来尝试元注解的用途,这里就不一一演示了。
  当然这个例子只是第一个简单的自定义注解实例,后面会出复杂的例子来演示自定义注解的妙用。

上一篇

评论系统未开启,无法评论!

如果有好的建议或疑问等可以发送邮件至:panhainan@yeah.net,或者添加QQ:1016593477,将你的建议或者疑问告诉作者,作者会对你的建议进行处理并补充到文章的尾部,谢谢大家的谅解!