ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java学习之路01-java注解(Annotation)01-java内置注解

2020-06-20 15:03:18  阅读:211  来源: 互联网

标签:01 java TestAnnotation class 注解 ElementType public String


java内置注解

作用在代码的注解

@Override

  • 重写注解,标注在方法上,无属性。

该注解告诉编译器,该方法是重写方法,编译器则会判断其实现的接口或其父类有无该方法,无则编译报错。

@Deprecated

  • 过时注解,标注在属性方法参数构造器局部变量上,无属性。

该注解表示该类或者方法为已经废弃的,只是为了兼容以前的程序,调用处也会出现删除线,不建议使用,建议使用新的方法或者类。

Java 9 中注解增加了两个新属性:
since: 该属性指定已注解的API元素已被弃用的版本。
forRemoval: 改属性表示注解的 API 元素在将来的版本中被删除,应该迁移 API。*

@SuppressWarnings

  • 抑制编译器警告注解,标注在属性方法参数构造器局部变量上,属性为String[] value()

该注解的作用是告诉编译器取消标注代码的指定的警告。
@SuppressWarnings("unchecked") 抑制单类型的警告
@SuppressWarnings({"unchecked","rawtypes"}) 抑制多类型的警告
@SuppressWarnings("all") 抑制所有类型的警告
建议把注解放在最近进警告发生的位置。

@SafeVarargs

  • 抑制堆污染警告注解,标注在构造器方法上,无属性。

该注解的作用是告诉编译器取消unchecked警告。

unchecked警告是什么?
Heap Pollution堆污染,首先我们看下什么是堆污染:

某个 可变泛型参数 指向的对象 并不是该泛型参数,而是无泛型参数。

举个栗子:

	//此时test方法的入参是List<String>
	public static void test(List<String> list) {
	}
	public static void main(String[] args) {
	        List list = Lists.newArrayList();
	        list.add(1);
	        //test方法的入参(可变泛型参数)指向的并不是List<String>,而是List(无泛型参数)
	        test(list);
	}

这种情况就会发生堆污染,此时编译器会提示我们unchecked警告。
在这里插入图片描述
而堆污染还可能导致ClassCastException异常,比如在test方法体中添加对List<Integer>的操作。

public static void main(String[] args) {
        List list = Lists.newArrayList();
        list.add(1);
        test(list);
    }

    public static void test(List<String> list) {
        String a = list.get(0);
    }

在这里插入图片描述
运行代码抛出ClassCastException异常
所以在使用@SafeVarargs注解时,保证在不会出现ClassCastException异常时,加到方法上以消除警告。

使用的时候要注意:@SafeVarargs注解,对于非static或非final声明的方法,不适用,会编译不通过。

@FunctionalInterface

  • 函数式接口注解,标注在接口上,无属性

该注解只能标志在"有且仅有一个抽象方法"的接口上。
有且仅有一个抽象方法不包括JDK8接口中的静态方法和默认方法,不包括覆盖了Object中方法。
该注解不是必须的,如果一个符合函数式接口要求的接口加不加该注解都可以,但是如果不满足要求加该注解则会编译报错。

举个栗子:

@FunctionalInterface
public interface TestInterface {
	//唯一的抽象方法
    public void test();

    public int hashCode();

    public static void test1(){

    }

}

作用在注解的注解(元注解)

@Target

  • 指定注解的使用范围
  • ElementType.TYPE:类、接口、注解、枚举
  • ElementType.FIELD:字段、枚举常量
  • ElementType.METHOD:方法
  • ElementType.PARAMETER:形式参数
  • ElementType.CONSTRUCTOR:构造方法
  • ElementType.LOCAL_VARIABLE:局部变量
  • ElementType.ANNOTATION_TYPE:注解
  • ElementType.PACKAGE:包
  • ElementType.TYPE_PARAMETER:类型参数

举个栗子:

@Target(ElementType.TYPE_PARAMETER)
@Retention(RetentionPolicy.CLASS)
public @interface TestAnnotation {

}

class Test<@TestAnnotation T> {
    
    public <@TestAnnotation U> U foo(U u) {
        return null;
    }
}
  • ElementType.TYPE_USE:类型使用

可以指定任何类型,举个栗子:

@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.CLASS)
public @interface TestAnnotation {

    String value() default "a";

}

@TestAnnotation
@interface TestAnnotation1 {

}

@TestAnnotation
class Test<@TestAnnotation T> {

    @TestAnnotation Test() {
    }

    @TestAnnotation
    private Integer n;

    @TestAnnotation
    public <@TestAnnotation U> U foo(U u) {
        return null;
    }

    @TestAnnotation
    public String fun(@TestAnnotation Integer a) {
        @TestAnnotation
        Integer b = a;
        Object o = (@TestAnnotation Object) a;
        @TestAnnotation String text = (@TestAnnotation String) new Object();
        n = b;
        return "1";
    }

}

注意:当使用 ElementType.TYPE_USE时,方法的返回值若为void,则不可以被使用。
在这里插入图片描述

@Retention

  • 用于指定注解的保留策略
  • RetentionPolicy.SOURCE:注解只保留在源码中,在编译时会被编译器丢弃
    栗子:@Override
  • RetentionPolicy.CLASS:(默认的保留策略) 注解会被保留在Class文件中,但不会被加载到虚拟机中,运行时无法获得
  • RetentionPolicy.RUNTIME:注解会被保留在Class文件中,且会被加载到虚拟机中,可以在运行时获得
    栗子:@Deprecated

@Documented

  • 用于将注解包含在javadoc中

javadoc是Sun公司提供的一个技术,它从程序源代码中抽取类、方法、成员等注释形成一个和源代码配套的API帮助文档。也就是说,只要在编写程序时以一套特定的标签作注释,在程序编写完成后,通过Javadoc就可以同时形成程序的开发文档了。

默认情况下,javadoc是不包括注解的,但如果使用了@Documented注解,则相关注解类型信息会被包含在生成的文档中

@Inherited

  • 用于指明父类注解会被子类继承得到

举个栗子:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface TestAnnotation {

    String value();

}

@TestAnnotation("test")
class Parent{

}

class Son extends Parent{
    public static void main(String[] args) {
        TestAnnotation annotation = Son.class.getAnnotation(TestAnnotation.class);
        System.out.println(annotation.value());
    }
}

@Repeatable

  • 用于声明标记的注解为可重复类型注解,可以在同一个地方多次使用

举个栗子:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(BaseAnnotation.class)
public @interface TestAnnotation {

    String value();

}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface BaseAnnotation {

    TestAnnotation[] value();

}

@TestAnnotation("test")
@TestAnnotation("test1")
@TestAnnotation("test2")
class Son {
    public static void main(String[] args) {
        BaseAnnotation annotations = Son.class.getAnnotation(BaseAnnotation.class);
        for (TestAnnotation annotation : annotations.value()) {
            System.out.println(annotation.value());
        }
    }
}

标签:01,java,TestAnnotation,class,注解,ElementType,public,String
来源: https://blog.csdn.net/qq_41909425/article/details/106836081

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有