【JavaSE】注解

尚硅谷JavaSE笔记合集

文章名链接
【JavaSE】异常文章地址
【JavaSE】常用类:String、LocalDateTime…文章地址
【JavaSE】枚举文章地址
【JavaSE】注解文章地址
【JavaSE】集合框架文章地址 | HashMap源码解析 | List相关实现类源码解析
【JavaSE】泛型文章地址
【JavaSE】IO流文章地址 | 字符编码详解
【JavaSE】网络编程,BIO需求演进文章地址
【JavaSE】反射文章地址
【JavaSE】jdk8新特性文章地址

一、理解

  • JDK 5.0 新增的对元数据(MetaData) 的支持
  • Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理。
    • 通过使用Annotation, 程序员可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息。
    • 代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。
  • 在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。
  • 在JavaEE/Android中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替JavaEE旧版中所遗留的繁冗代码和XML配置等。

未来的开发模式都是基于注解的,JPA是基于注解的,Spring2.5以上都是基于注解的,Hibernate3.x以后也是基于注解的,现在的Struts2有一部分也是基于注解的了。

注解是一种趋势,一定程度上可以说:框架= 注解+ 反射+ 设计模式

二、常见注解

使用Annotation 时要在其前面增加@ 符号, 并把该Annotation 当成一个修饰符使用。用于修饰它支持的程序元素

2.1 文档生成

  • @Description:类描述

  • @author:标明开发该类模块的作者,多个作者之间使用,分割

  • @version:标明该类模块的版本

  • @see:参考转向,也就是相关主题

  • @since:从哪个版本开始增加的

  • @param:对方法中某参数的说明,如果没有参数就不能写

    • 只用于方法
    • 格式要求:@param 形参名 形参类型,形参说明
    • 可以并列多个
  • @return:对方法返回值的说明,如果方法的返回值类型是void就不能写

    • 只用于方法
    • 格式要求:@return 返回值类型 返回值说明
  • @exception:对方法可能抛出的异常进行说明,如果方法没有用throws显式抛出的异常就不能写

    • 只用于方法

    • 格式要求:@exception 异常类型 异常说明

    • 可以并列多个

/**
 * @Decription 常见的Annotation示例
 * @author 李泽伟
 * @version v1.0
 */
public class CommonAnnotation {
    /**
     *
     * @param args String[] 命令行参数
     */
    public static void main(String[] args) {
        @SuppressWarnings("unused")
        String str="a";
    }
}

2.2 格式检查

  • @Override: 限定重写父类方法, 该注解只能用于方法
  • @Deprecated: 用于表示所修饰的元素(类, 方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择
  • @SuppressWarnings: 抑制编译器警告
    • unused:未被使用警告
    • rawtypes:未指定泛型警告
public class CommonAnnotation {
    public static void main(String[] args) {
        @SuppressWarnings("unused")	//抑制未使用警告
        String str="a";
    }
}
class Student extends Person implements Sport{
    //@Override 重写、实现的标记:用于编译时检查,如果标记为@Override但方法名无法匹配则编译不通过
    public void eat() {
        System.out.println("学生吃饭!");
    }
    @Override
    public void doSport() {

    }
}
class Person{
    public void eat(){
        System.out.println("人吃饭!");
    }
}
interface Sport{
    void doSport();
}

2.3 依赖性跟踪

跟踪代码依赖性,实现替代配置文件功能

  • Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署。

    @WebServlet(value = {"/auth","/login"})
    public class AuthServlet extends ModelBaseServlet {
    }
    
  • spring框架中关于“事务”的管理

    @Transactional(propagation= Propagation.REQUIRES_NEW,isolation= Isolation.DEFAULT)
    public Emp getEmpByLogin(String loginAccount, String loginPassword) {
    }
    

三、自定义Annotation

自定义注解必须配上注解的信息处理流程才有意义

  • 自动继承:java.lang.annotation.Annotation 接口
  • 成员变量如果没有指定默认值,使用时必须指定参数值
  • 注解类型:
    • 标记:没有定义成员变量
    • 元数据:包含成员变量
/**
 *	2.自定义Annotation
 *      ① 注解声明:@interface
 *      ② 内部定义成员,通常使用value表示。指定参数值可以省略 value=
 *      ③ 可以指定成员的默认值,使用default定义
 *		④ 成员类型可以是:八种基本数据类型、String、Class、enum、Annotation、以上所有类型的数组。
 *
 *      自定义注解通过都会指明两个元注解:Retention、Target
 *
 */
public @interface MyAnnotation {
    String value() default "Hi";
}

四、四个基本的元注解

元注解:

  • 对现有的注解进行解释说明,只能用于修饰注解定义的注解
  • JDK5.0提供了4个标准的元注解

4.1 @Retention

  • 作用:指定注解的生命周期
  • 成员变量:value
  • RetentionPolicy.SOURCE:在源文件中有效(即.java文件保留)
    • 编译时丢弃所修饰的注解
    • RetentionPolicy.CLASS(默认):在字节码文件中有效(即.class保留)
      • 运行时丢弃所修饰的注解
    • RetentionPolicy.RUNTIME:在运行时有效(即加载到内存中参与运行)
      • 运行时保留所修饰的注解。
      • 程序可以通过反射获取该注释。

在这里插入图片描述

@Retention(RetentionPolicy.RUNTIME)
public @interface MetaAnnotation {
    String value() default "Hello";
}

4.2 @Target

  • 作用:指定注解 能用于修饰哪些程序元素
  • 成员变量:value[]
    • ElementType.TYPE:类、接口、注解、枚举类
    • ElementType.CONSTRUCTOR:构造器
    • ElementType.METHOD:方法
    • ElementType.FIELD:属性
    • ElementType.LOCAL_VARIABLE:局部变量
    • ElementType.PACKAGE:包
    • ElementType.PARAMETER:参数
    • ElementType.TYPE_PARAMETER
    • ElementType.TYPE_USE
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MetaAnnotation {
    String value() default "Hello";
}

4.3 @Documented

  • 作用:在生成的文档中保留被修饰的注解。默认情况下,javadoc是不包括注解的。

    • @Retention值必须设置为RUNTIME。
  • 使用前

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface MetaAnnotation {
        String value() default "Hello";
    }
    

在这里插入图片描述

  • 使用后

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    public @interface MetaAnnotation {
        String value() default "Hello";
    }
    

在这里插入图片描述

4.4 @Inherited

  • 作用:被修饰的注解 将具有继承性。

    • 如果某个类使用了被@Inherited 修饰的注解,则其子类将自动具有该注解。
  • 实际应用中,使用较少

  • 定义可继承注解

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @Inherited
    public @interface MetaAnnotation {
        String value() default "Hello";
    }
    
  • 使用注解

    @MetaAnnotation
    class Person{
    }
    class Student extends Person{
    }
    /**
     * 反射获取注解信息
     */
    public class ReflectAnnotation {
        public static void main(String[] args) {
            Class clazz=Student.class;
            Annotation[] annotations = clazz.getAnnotations();
            for (Annotation annotation : annotations) {
                //@org.example.java.MetaAnnotation(value=Hello)
                System.out.println(annotation);
            }
        }
    }
    

五、反射获取注解信息

参考 2.4.4

/**
 * 反射获取注解信息
 */
public class ReflectAnnotation {
    public static void main(String[] args) {
        Class clazz=Student.class;
        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            //@org.example.java.MetaAnnotation(value=Hello)
            System.out.println(annotation);
        }
    }
}

六、jdk8新特性

Java 8对注解处理提供了两点改进:可重复的注解及可用于类型的注解。

此外,反射也得到了加强,在Java8中能够得到方法参数的名称。这会简化标注在方法参数上的注解。

6.1 可重复注解

  • ① 在RepeatableDemo上声明@Repeatable,成员值为RepeatableDemos.class
  • RepeatableDemo的 @Target和@Retention 等元注解与MyAnnotations相同。
@RepeatableDemo(value = "A")
@RepeatableDemo(value = "B")
//@RepeatableDemos({@RepeatableDemo(value = "A"),@RepeatableDemo(value = "B")})
public class Jdk8Annotation {
}

@Repeatable(RepeatableDemos.class)
@interface RepeatableDemo{
    String value() default "Hello";
}
@interface RepeatableDemos{
    RepeatableDemo[] value();
}

6.2 类型注解

  • 元注解@Target 成员变量值类型 ElementType 多了两个
    1. ElementType.TYPE_PARAMETER:注解能写在类变量的声明语句中(如:泛型声明)
    2. ElementType.TYPE_USE:注解能写在使用类型的任何语句中
//使用
//1.TYPE_PARAMETER
public class Jdk8Annotation <@AboutType T>  {
    public void demo(){
        //2.TYPE_USE
        ArrayList<@AboutType String> list=new ArrayList();
    }
}

//定义
@Target({ElementType.TYPE_USE,ElementType.TYPE_PARAMETER})
@interface AboutType{
    String value() default "Hi";
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愿你满腹经纶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值