JAVA从零学习(二)注解Annotation

在我们使用Spring开发JAVA的程序或多或少都有用到过注解(即@XXXXX),一般在类的定义、方法定义,属性定义上方。
JDK5.0中提供了注解的功能,允许开发者定义和使用自己的注解类型。该功能由一个定义注解类型的语法和描述一个注解声明的语法,读取注解的API,一个使用注解修饰的class文件和一个注解处理工具组成。
Annotation并不直接影响代码的语义,但是他可以被看做是程序的工具或者类库。它会反过来对正在运行的程序语义有所影响。
Annotation可以冲源文件、class文件或者在运行时通过反射机制多种方式被读取

为什么学习注解
  • 能读懂别人写的代码,特别是底层框架相关的代码
  • 让编程更加简介,代码更加清晰
  • 装逼利器
注解分类
  • 按照运行机制分
    • 源码注解:注解只在源码中存在,编译成.class文件时丢失
    • 编译时注解:在源码和.class文件中都存在,运行时丢失
    • 运行时注解:源码、class文件、运行时都存在,甚至影响运行逻辑
  • 按照来源划分
    • JDK自带注解:(Java目前只内置了三种标准注解:@Override、@Deprecated、@SuppressWarnings,以及四种元注解:@Target、@Retention、@Documented、@Inherited)
    • 第三方注解:接触最多,使用最多的注解Spring、Mybatis等
    • 自定义注解:咱自己写的注解
  • 按照功能划分
    • 元注解:注解的注解(JAVA自带)
    • 一般注解
JAVA自带注解
注解 用途
@Override 覆盖或重写父类的方法
@Deprecated 表示该方法已经过时了。(当方法或是类上面有@Deprecated注解时,说明该方法或是类都已经过期不能再用,但不影响以前项目使用,提醒你新替代的方法或是类。如果程序员不小心使用了它的元素,那么编译器会发出警告信息。)
@SuppressWarnings 表示忽略指定警告,比如@Suppvisewarnings(“Deprecation”)
常见第三方注解
注解 用途
Spring @Autowired 自动注册成员变量
Spring @Service 业务层定义
Spring @Repository 持久层定义/数据访问组件(一般为自定义注解DAO层例如@MyBatisDao)
Spring @Controller 控制层定义
Spring @Component 中立类进行注解/泛指组建
Mybatis @Insert 直接配置SQL语句
Mybatis @Select 直接配置SQL语句
Mybatis @Update 直接配置SQL语句
Mybatis @Delete 直接配置SQL语句
Mybatis @InsertProvider 通过SQL工厂类及对应的方法生产SQL语句(最常用)
Mybatis @UpdateProvider 通过SQL工厂类及对应的方法生产SQL语句(最常用)

Spring在启动时,自动扫描机制会自动扫描带有这些注解的类放到Spring容器中

自定义注解

自定义注解使用必须是@interface标记(明确这不是一个接口,它是使用@interface关键字定义的一个注解),事例代码如下:

/**
 * @Project : ${PROJECt_NAME}
 * @Package Name : com.codeyi.annotation.impl
 * @Author Codeyi on 2018-02-07.
 * @Creation Date: 2018年02月07日 14:31
 * 自定义注解
 */

@Target({ElementType.METHOD,ElementType.TYPE,ElementType.ANNOTATION_TYPE,ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.LOCAL_VARIABLE,ElementType.PACKAGE,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyAnnotation {
    /*
    ①.成员类型是受限制的,合法的类型包括基本的数据类型以及String,Class,Annotation,Enumeration等。
    ②.如果注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=)。
    ③.注解类可以没有成员,没有成员的注解称为标识注解。
     */
    int id() default 0;
    String name();
}
  • @Target是这个注解的作用域
参数 说明
CONSTRUCTOR (构造方法声明)
FIELD (字段声明)
LOCAL VARIABLE (局部变量声明)
METHOD (方法声明)
PACKAGE (包声明)
PARAMETER (参数声明)
TYPE (类接口)

- @Retention是它的生命周期

参数 说明
SOURCE (只在源码显示,编译时丢弃)
CLASS (编译时记录到class中,运行时忽略)
RUNTIME (运行时存在,可以通过反射读取)

- @Inherited是一个标识性的元注解,它允许子注解继承它。
- @Documented,生成javadoc时会包含注解。

参数
  • 成员类型是受限制的,合法的类型包括基本的数据类型以及String,Class,Annotation,Enumeration等。
  • 如果注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=)。
  • 注解类可以没有成员,没有成员的注解称为标识注解。
注解的使用

@<注解名>(<成员名1>=<成员值1>,<成员名1>=<成员值1>,…)

上面事例我们自定义了一个注解,下面我们就来尝试使用自定义注解完成一些我们想要的功能

**
 * @Project : ${PROJECt_NAME}
 * @Package Name : com.codeyi.annotation
 * @Author Codeyi on 2018-02-07.
 * @Creation Date: 2018020714:38
 */

@MyAnnotation(id = 1, name = "MethodTest")
public class Test {
    @MyAnnotation(id = 1, name = "A")
    public void A() {

    }

    @MyAnnotation(id = 2, name = "B")
    public void B() {

    }

    @MyAnnotation(id = 3, name = "C")
    public void C() {

    }

    public static void main(String[] args) {
        try {
            // 使用类加载器加载类
            Class myClasses = Class.forName("com.codeyi.annotation.Test");
            //获取所有的方法
            Method[] ms = myClasses.getMethods();
            // 找到类上面的注解
            boolean isExist = myClasses.isAnnotationPresent(MyAnnotation.class);
            // 上面的这个方法是用这个类来判断这个类是否存在Description这样的一个注解
            if (isExist) {
                // 拿到注解实例,解析类上面的注解
                MyAnnotation d = (MyAnnotation) myClasses.getAnnotation(MyAnnotation.class);
                System.out.println(d.name());
            }
            // 遍历所有的方法
            for (Method m : ms) {
                // 找到类上面的注解
                isExist = m.isAnnotationPresent(MyAnnotation.class);
                // 上面的这个方法是用这个类来判断这个类是否存在MyAnnotation这样的一个注解
                if (isExist) {
                    // 拿到注解实例,解析类上面的注解
                    MyAnnotation myAnnotation = m.getAnnotation(MyAnnotation.class);
                    System.out.print(myAnnotation.id() + "-" + myAnnotation.name());
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

测试结果

MethodTest
2-B3-C1-A
Process finished with exit code 0

完美,那有这些了我们能做些什么呢?大家可以想想,很精彩的哦欢迎找本人讨论。

请大家关注下一课。

本文由Codeyi原创(包括图文)转载请注明出处

你可能感兴趣的:(Java,JAVA,注解)