java基础-注解

1.概念

是一种特殊标记,出现在jdk1.5后。类,方法,变量,参数和包都可以被标注。跟注释的区别就是注释是给程序员看的,而注解只给程序看的。

2.java 内置的注解

1. @Override

检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。

2. @Deprecated

标记过时方法、类。如果使用该方法,会报编译警告。

3. @SuppressWarnings

抑制编译器警告

例如

	@SuppressWarnings({ "rawtypes", "unused" })
    List list1 = new ArrayList();

在实例化ArrayList 时没有指定泛型,因此使用 @SuppressWarnings 抑制编译器警告
@SuppressWarnings 的常用参数:

参数含义
deprecation使用了不赞成使用的类或方法时的警告(使用@Deprecated使得编译器产生的警告)
unchecked执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型; 关闭编译器警告
fallthrough当 Switch 程序块直接通往下一种情况而没有 Break 时的警告
path在类路径、源文件路径等中有不存在的路径时的警告
serial当在可序列化的类上缺少 serialVersionUID 定义时的警告
finally任何 finally 子句不能正常完成时的警告
rawtypes泛型类型未指明
unused引用定义了,但是没有被使用
all关于以上所有情况的警告

4. @SafeVarargs

  • Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。

5. @FunctionalInterface

  • Java 8 开始支持,标识一个匿名函数或函数式接口。

3.元注解

元注解就是作用在注解上的注解

1.@Retention

指明注解的生命周期,标识这个注解怎么保存,是只在源代码中,还是编入class文件中,或者是在运行时可以通过反射访问。

成员变量Value指定值含义
RetentionPolicy.SOURCE只存在代码中,会被编译器抛弃
RetentionPolicy.CLASS默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
RetentionPolicy.RUNTIME注解会在class字节码文件中存在,在运行时可以通过反射获取到

2.@Documented

标记这些注解是否包含在用户文档中。

注意:设置 @Documented 注解的 @Retention 必须为 RUNTIME

3.@Target

表示我们的注解作用的范围

例如

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}
public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    //作用接口、类、枚举、注解
    TYPE,
    
    /** Field declaration (includes enum constants) */
    //作用属性
    FIELD,
    
    /** Method declaration */
    //作用方法
    METHOD,
    
    /** Formal parameter declaration */
    // 作用方法参数
    PARAMETER,
    
    /** Constructor declaration */
    //作用构造函数
    CONSTRUCTOR,
    
    /** Local variable declaration */
    //作用局部变量
    LOCAL_VARIABLE,
    
    /** Annotation type declaration */
    //作用注解
    ANNOTATION_TYPE,
    
    /** Package declaration */
    //作用于包  
    PACKAGE,
    
    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    //作用于类型泛型,即泛型方法、泛型类、泛型接口 
    TYPE_PARAMETER,
    
    /**
     * Use of a type
     *
     * @since 1.8
     */
    //作用于类型使用.可以用于标注任意类型除了 class
    TYPE_USE
}

4.@Inherited

一个被 @Inherited 注解了的注解修饰了一个父类,如果他的子类没有被其他注解修饰,则它的子类也继承了父类的注解。也就是使得注解具有继承性。

5.@Repeatable

可重复注解。被这个元注解修饰的注解可以同时作用一个对象多次,但是每次作用注解又可以代表不同的含义。

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface myannotattions {
    myAnnotation[] value();
}

@Repeatable(myannotattions.class)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface myAnnotation {
   String[] value();
}

@com.annotation.myAnnotation("ls1")
@com.annotation.myAnnotation("ls")
public class collectionTest01 {

4.自定义注解(配合反射)

可以先来看一下 @SuppressWarnings 中的内容,参照 @SuppressWarnings 来自定义注解

public @interface SuppressWarnings {
    /**
     * The set of warnings that are to be suppressed by the compiler in the
     * annotated element.  Duplicate names are permitted.  The second and
     * successive occurrences of a name are ignored.  The presence of
     * unrecognized warning names is <i>not</i> an error: Compilers must
     * ignore any warning names they do not recognize.  They are, however,
     * free to emit a warning if an annotation contains an unrecognized
     * warning name.
     *
     * <p> The string {@code "unchecked"} is used to suppress
     * unchecked warnings. Compiler vendors should document the
     * additional warning names they support in conjunction with this
     * annotation type. They are encouraged to cooperate to ensure
     * that the same names work across multiple compilers.
     * @return the set of warnings to be suppressed
     */
    String[] value();
}

只有一个 String[] value();
这是一个成员变量。因为在注解中的成员变量是以无参方法的形式来申明。而这个String[] 为该变量的类型,可以给该成员赋一个默认值

public @interface myAnnotation {
    String[] value() default "ls";
}

如果没有默认值时,在使用注解的时候要赋值

@com.annotation.myAnnotation("ls")
public class collectionTest01 {
}

注解中定义属性时它的类型必须是 8 种基本数据类型外加 类、接口、注解及它们的一维数组。

value 是注解中的一个特殊属性,如果注解中只有它这一个属性时,我们在使用注解的时候可以省略value=部分,直接写成myAnnotation(“ls”),如果不是,则要写成 @myAnnotation(ans =“ls1”)

public @interface myAnnotation {
   String[] ans();
}

5.注解的简单使用

上面我们将的都是注解的内容,接下来讨论注解的作用。
官方解释:

注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释的代码本身的一部分。注解对于代码的运行效果没有直接影响。

可以把注解想象成一个标签,他是用来解释代码的。对于java内置的注解,我们可以直接在类、方法、属性上修饰,而对于我们自定义注解,可以通过反射提取注解的信息,根据注解信息,告诉程序如何去运行类

在框架中,注解的使用非常多,比如spring中的@Component 就是告诉spring需要把该类当成bean放入容器中

注解内容的提取

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface myAnnotation {
   String[] ans();
   int age() default 10;
}

@myAnnotation(ans = "example")
public class example {
    String value;

    @myAnnotation(ans = "test1,test2",age = 20)
    public int test(){
        return 0;
    }
}
public class anno {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        //通过反射获取example类的Class对象
        Class<?> aClass = Class.forName("com.annotation.example");
        System.out.println(aClass);

        //获取类上的注解信息
        myAnnotation myannotation = aClass.getAnnotation(myAnnotation.class);
        System.out.println(Arrays.toString(myannotation.ans()) + myannotation.age());

        //获取方法上的注解信息
        Method method1 = aClass.getMethod("test");
        //判断该方法上是否右myAnnotation注解
        if(method1.isAnnotationPresent(myAnnotation.class)){
            System.out.println(Arrays.toString(myannotation.ans()) + myannotation.age());
        }
    }
}

注解使用最终是需要依靠特定的程序去读取注解,得到注解的一些信息,根据注解的信息来确定接下来该做什么。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值