Java注解

1、注解是什么?

  1. 注解,或者叫做注释类型,英文单词是:Annotation
  2. 注解Annotation是一种引用数据类型。编译之后也是生成xxx.class文件。

2、怎么自定义注解呢?语法格式?

[修饰符列表] @interface 注解类型名{

}

3、注解怎么使用,用在什么地方?

3.1、注解使用时的语法格式

@注解类型名

3.2、注解可以出现的地方

  1. 注解可以出现在上、属性上、方法上、变量上等…
  2. 注解还可以出现在注解类型上。

eg.

package javase.annotation1;

// 默认情况下,注解可以出现在任意位置。

@MyAnnotation
public class AnnotationTest01 {
    @MyAnnotation
    int no;

    @MyAnnotation
    public AnnotationTest01(int no) {
        this.no = no;
    }

    @MyAnnotation
    public void m1(){
        @MyAnnotation
        int i;
    }

    public void m2(@MyAnnotation String name, @MyAnnotation boolean sex){

    }
}

@MyAnnotation
interface MyInterface{

}

@MyAnnotation
enum Season{
    @MyAnnotation SPRING, @MyAnnotation SUMMER,AUTUMN,WINTER
}

@MyAnnotation
abstract class a{

}

----------------------------------------------
package javase.annotation1;

//注解修饰注解
@MyAnnotation
public @interface OtherAnnotation {
}

4、JDK内置了哪些注解呢?

java.lang包下的注释类型:

注解解释备注
Deprecated表示不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。掌握
Override表示一个方法声明打算重写超类中的另一个方法声明。掌握
SuppressWarnings指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。不用掌握

5、元注解

5.1、什么是元注解?

用来标注注解类型”的“注解”,称为元注解。

5.2、常见的元注解有哪些?

  • Target
  • Retention

5.3、关于Target注解

  • 这是一个元注解,用来 标注“注解类型” 的“注解”
  • 这个Target注解用来标注“被标注的注解可以出现在哪些位置上

eg.

@Target(ElementType.METHOD):表示“被标注的注解”只能出现在方法上。

@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
表示该注解可以出现在:
构造方法上
字段上
局部变量上
方法上
....
类上...

5.3.1、关于Target注解的常量

表示该注解可以出现在什么位置上

常量名位置
TYPE
FIELD属性
METHOD方法
CONSTRUCTOR构造方法
LOCAL_VARIABLE局部变量
PACKAGE
MODULE模块
PARAMETER方法参数

5.4、关于Retention注解

  • 这是一个元注解,用来 标注“注解类型” 的“注解”
  • 这个Retention注解用来标注“被标注的注解””最终保存在哪里

eg.

@Retention(RetentionPolicy.SOURCE):表示该注解只被保留在java源文件中。
@Retention(RetentionPolicy.CLASS):表示该注解被保存在class文件中。
@Retention(RetentionPolicy.RUNTIME):表示该注解被保存在class文件中,并且可以被反射机制所读取。

5.4.1、关于Retention注解的常量

表示该注解保存在什么地方

常量名位置
SOURCE表示该注解只被保留在java源文件中
CLASS表示该注解被保存在class文件中
RUNTIME表示该注解被保存在class文件中,并且可以被反射机制所读取。

6、关于JDK lang包下的Override注解

6.1、源代码

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

6.2、解释

  • 标识性注解,给编译器做参考的。
  • 编译器看到方法上有这个注解的时候,编译器会自动检查该方法是否重写了父类的方法。如果没有重写,报错。
  • 这个注解只是在编译阶段起作用,和运行期无关!
  • @Override这个注解只能注解方法

7、关于JDK lang包下的Deprecated注解

7.1、源代码

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

7.2、解释

  • Deprecated这个注解标注的元素已过时
  • 这个注解主要是向其它程序员传达一个信息,告知已过时,有更好的解决方案存在

eg.
在这里插入图片描述

8、注解的属性

我们通常在注解当中可以定义属性,以下这个是MyAnnotation的name属性。
看着像1个方法,但实际上我们称之为属性name。

public @interface MyAnnotation {
    String name();//名字属性
    String color();//颜色属性
    int age() default 25; //属性指定默认值
}

注:如果一个注解当中有属性,那么必须给属性赋值。(除非该属性使用default指定了默认值。)

eg.

public class AnnotationTest {
    // 报错的原因:如果一个注解当中有属性,那么必须给属性赋值。(除非该属性使用default指定了默认值。)
    /*@MyAnnotation
    public void doSome(){
    }*/

    //以下两种都可以
//    @MyAnnotation(name = "张三", color = "红色", age = 30)//覆盖掉默认值25
    @MyAnnotation(name = "张三", color = "红色")
    public void doSome(){
    }
}

8.1、属性赋值语法格式:

@注解(属性名=属性值,属性名=属性值,属性名=属性值)

8.2、★注解的value属性

注:如果一个注解的属性的名字是value,并且只有一个属性的话,在使用的时候,该属性名可以省略。(数据value属性名也可以省略)

eg.

public @interface MyAnnotation {
    String value();
}
---------------------------------------------
public class AnnotationTest {
    //以下两种都可以
//    @MyAnnotation(value = "123")
    @MyAnnotation("123")
    public void doSome(){
    }
}

8.3、注解属性的数据类型

八大基本数据类型 + 3大引用类型【String、Class、enum】(包括这些类型的数组形式!)

  1. bite
  2. short
  3. int
  4. long
  5. float
  6. double
  7. boolean
  8. char
  9. String
  10. Class
  11. enum枚举类型

8.4、注解属性数组的注意事项

数组是大括号 如果数组中只有1个元素:大括号可以省略。*

eg.

public @interface MyAnnotation {
    /*
        注解当中的属性可以是哪一种类型?
            属性的类型可以是:
                byte short int long float double boolean char String Class 枚举类型
                以及以上每一种的数组形式。
    */
    int no() default 1;
    int[] score();
    String name() default "null";
    String[] email();//邮箱地址属性,支持多个
    Season[] seasonArray();//季节数组,Season是枚举类型
    Class parameter1() default Date.class;
    Class[] parameter2();
}
------------------------------------------------------------
public class AnnotationTest {
    // 数组是大括号
    @MyAnnotation(no = 1900129, score = {90, 98, 70},
            email = {"192@qq.com", "ouw@sgu.com"},
            seasonArray = {Season.SPRING, Season.SUMMER},
            parameter2 = {int.class, String.class})
    public void doSome(){
    }

    // 如果数组中只有1个元素:大括号可以省略。
    @MyAnnotation(score = 90, email = "ouw@sgu.com",
            seasonArray = Season.SUMMER, parameter2 = String.class)
    public void doOther(){
    }
}

9、反射类上的注解

四步骤:

  1. 获取这个类
  2. 判断类上面是否有注解
  3. 获取注解对象
  4. 获取注解对象的属性

eg.

//反射类上的注解
public class ReflectAnnotationTest {
    public static void main(String[] args) throws Exception{
        // 获取这个类
        Class c = Class.forName("javase.annotation5.AnnotationTest");
        // 判断类上面是否有@MyAnnotation
//        System.out.println(c.isAnnotationPresent(MyAnnotation.class));
        if (c.isAnnotationPresent(MyAnnotation.class)){
            // 获取注解对象的属性怎么办?和调接口没区别。
            MyAnnotation myAnnotation = (MyAnnotation)c.getAnnotation(MyAnnotation.class);
            // 获取注解对象的属性怎么办?和调接口没区别。
            String value = myAnnotation.value();
            System.out.println(value);
        }

        // 判断String类上面是否存在这个注解
        Class stringClass = Class.forName("java.lang.String");
        System.out.println(stringClass.isAnnotationPresent(MyAnnotation.class)); // false
    }
}
----------------------------------------------
@MyAnnotation("zhangSan")
public class AnnotationTest {

    @MyAnnotation
    public void doSome(){

    }
}

10、反射方法上的注解

五步骤:

  1. 获取这个类
  2. 获取这个类的方法
  3. 判断类的方法上面是否有注解
  4. 获取注解对象
  5. 获取注解对象的属性

eg.

public class MyAnnotationTest {
    @MyAnnotation(name = "admin", pwd = "123")
    public void doSome(){
    }

    public static void main(String[] args) throws Exception{
        // 获取MyAnnotationTest的doSome()方法上面的注解信息。
        Class c = Class.forName("javase.annotation6.MyAnnotationTest");
        // 获取doSome()方法
        Method method = c.getDeclaredMethod("doSome");
        // 判断该方法上是否存在这个注解
        if (method.isAnnotationPresent(MyAnnotation.class)){
            MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
            String name = annotation.name();
            String pwd = annotation.pwd();
            System.out.println(name + " " + pwd);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值