JAVA注解 —— 运用和自定义注解

JAVA开发 workingTime 899℃ 0评论

注解(也被称为元数据)为我们在代码中添加信息提供了一种形式的方法,使我们可以在稍后某个时刻非常方便的使用这些数据

Java内置注解(在java.lang包下)

注解 说明
@Override 表示当前的方法定义将覆盖父类中的方法。
如果子类中覆盖父类的方法名称拼写错误,或者方法签名对不上被覆盖的方法,
将发出错误提示
@Deprecated 用于表示某个程序元素(类、方法等)已过时。
如果使用了被@Deprecated修饰的类或方法等,编译器会发出警告。
@SuppressWarnings 关闭不当的编译器警告。
@SafeVarargs jdk1.7新增。专门为抑制“堆污染”警告提供的
@FunctionalInterface jdk1.8新增。改注解标记在接口上。“函数式接口”是指仅仅只包含一个抽象方法的
接口。如果一个接口中包含不止一个抽象方法,那么不能使用
@FunctionalInterface,编译会报错。

Java元注解

元注解是负责注解其他注解的注解

注解 说明
@Target 表示该注解可以用在什么地方。参数包括:
ElementType.CONSTRUCTOR:构造器的生命
ElementType.FIELD:域声明(包括enum实例)
ElementType.LOCAL_VARIABLE:局部变量声明
ElementType.METHOD:方法声明
ElementType.PACKAGE:包声明
ElementType.PARAMETER:参数声明
ElementType.TYPE:类、接口(包括注解类型)或enum声明
ElementType.TYPE_PARAMETER:(JDK1.8)新增类型参数声明
ElementType.TYPE_USE:(JDK1.8)使用的类型
@Retention 表示需要在声明级别保存该注解的信息。参数包括:
RetentionPolicy.SOURCE:只保留在源代码中,注解将被编译器丢弃
RetentionPolicy.CLASS:注解在class文件中可用,但会被VM丢弃
RetentionPolicy.RUNTIME:VM在运行期也保留,因此可以通过反射机制读取注解信息
@Documented 将此注解包含在javadoc中
@Inherited 允许子类继承父类的注解

注解的语法与定义形式

在编写自定义注解前,我们需要先了解注解的语法和定义形式。

  • 首先:注解是以@interface 关键字定义的
  • 其次:注解需要标明注解的生命周期,注解的修饰目标等信息,这些信息是通过元注解实现。

例子:


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface UserCase {
    
}

这个例子我是定义了一个名字是UserCase的注解,它可以用于方法声明,并且在JVM运行期也保留。上面的注解没有任何功能,接下将通过向注解中加入方法的方式来实现特定的需求。

实现一个简单的自定义注解

功能说明:现在的软件项目大多都是分布式,通过RESTful的接口调取数据,那么我们在使用springMVC制造接口时候就会面临一个API文档问题,现在我们就自定义一个注解,通过在方法上面加入相应的注解内容,自动扫描生成方法的API。

定义注解:


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * User: R&M www.rmworking.com/blog
 * Date: 2017/6/12
 * Time: 23:58
 * Test
 * org.thinkInJava.annotations
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiCase {
    public String value();
    public String notes() default "该方法没有说明";
    public String HttpMethod() default "GET";
}

ApiCase类定义了注解提供的接口方法。

注解运用:


public class UserController {

    @ApiCase(value = "用户登录", notes = "用户登录接口")
    public String login(String userName , String passwd){
        //这里是登录逻辑
        return "success";
    }

    @ApiCase(value = "用户注册" , notes = "用户注册接口" ,HttpMethod = "POST")
    public String register(String userName , String passwd){
            //这里是注册业务逻辑
        return "success";
    }
}

UserController类假设是一个sprinMVC的用户controller,其中login是登录接口,register是注册接口。

注解实现:


public class ApiCaseTracker {

    public static void trackApiCases(Class<?> cl) {
        for (Method m : cl.getDeclaredMethods()) {
            ApiCase api = m.getAnnotation(ApiCase.class);
            if (api != null) {
                System.out.println(cl.getName() + "接口api:[接口值:" + api.value() + "] [接口说明:" + api.notes() + "] [请求类型:" + api.HttpMethod() + "]");
                //useCases.remove(new Integer(uc.id()));
            }
        }

    }

    public static void main(String[] args) {

        trackApiCases(UserController.class);
    }
}

打印结果:


org.thinkInJava.annotations.UserController接口api:[接口值:用户注册] [接口说明:用户注册接口] [请求类型:POST]
org.thinkInJava.annotations.UserController接口api:[接口值:用户登录] [接口说明:用户登录接口] [请求类型:GET]

转载请注明:R&M » JAVA注解 —— 运用和自定义注解

喜欢 (0)or分享 (0)
发表我的评论
取消评论

表情

备案号:京ICP备14044161号;联系我:rm@rmworking.com