JavaSE之——注解入门

  • 各大框架都使用了很多注解,学习注解可以让我们更好的了解框架的运行原理
  • 一般公司自己会封装一些注解,了解注解的原理可以让我们获得更高效的开发
  • 掌握注解,我们可以有机会参与到公司框架的封装,得到个人能力的提升

一、什么是注解

  • Annotation 的作用:
    • 注解不是程序本身,但是它可以对程序做出解释(这点和 comment 相同)
    • 注解可以被其它程序(例如编译器)读取
  • Annotation 的格式:
    • 注解是以"@注释名"在代码中存在的
    • 还可以添加一些参数值,例如: @SuppressWarnings(value="unchecked")
  • Annotation 在哪里可以使用?
    • 可以用在 packgeclassmethodfield 等上面,相当于给它们添加了额外信息
    • 我们可以通过反射的机制来实现对这些元数据的访问

二、内置注解

  • @Override
    • 只适用于修饰方法,表示一个方法声明打算重写超类中的方法
  • @Deprecated
    • 可以用于修饰方法、属性、类
    • 表示这个方法已经过时,可以使用但是不建议使用
  • @SuppressWarnings
    • 用来抑制编译时的警告信息
    • 这个注解需要添加参数才能正常使用
      • @SuppressWarnings("all")
      • @SuppressWarnings("unchecked")
      • @SuppressWarnings(value={"unchecked","deprecated"})
      • 其它。。。
/**
 * @Title: 内置注解测试
 * @Description:
 * @author: QianYi
 * @date: 2020/10/19 - 21:23
 */
public class AnnotationTest1 {

    @Override   // 表示方法的重写
    public String toString() {
        System.out.println("test @Override");
        return "test @Override";
    }

    @Deprecated // 方法过时了,可以使用但是不建议使用
    public static void testDeprecated() {
        System.out.println("test @Deprecated");
    }

    @SuppressWarnings("all")    // 抑制警告,可以传递相关参数
    public void testSuppressWarnings() {
        ArrayList<Object> list = new ArrayList<>();
    }

    public static void main(String[] args) {
        testDeprecated();
    }
}

三、元注解

  • 元注解的作用:负责注解其它的注解
  • Java 中定义了4个标准的 meta-annotation (元注解)类型,分别是
    • @Target :用于描述注解可以用在什么地方
public @interface Target {
    ElementType[] value();
}
//------------------------------------------------------------------------
public enum ElementType {
    // 类、接口、枚举类
    TYPE,
    // 属性
    FIELD,
    // 方法
    METHOD,
    // 参数
    PARAMETER,
    // 构造器
    CONSTRUCTOR,
    // 局部变量
    LOCAL_VARIABLE,
    // 注释类型
    ANNOTATION_TYPE,
    // 包
    PACKAGE,
    // 参数类型
    TYPE_PARAMETER,
    // 使用类型
    TYPE_USE
}
  • @Retention :用于描述注解的生命周期(SOURCE<CLASS<RUNTIME)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}
// -----------------------------------------------
public enum RetentionPolicy {
    // 源码
    SOURCE,
    // class文件
    CLASS,
    // 运行
    RUNTIME
}
  • @Document :表示该注解将被包含在 javadoc
  • @Inherited :表示子类继承父类中的该注解

四、自定义注解

  • 使用 @interface 自定义注解时,就自动继承了 java.lang.annotation.Annotation 接口
  • 分析
    • @interface 用来声明一个注解,其格式为
public @interface 注解名{
	注解的内容
}
  • 其中的每个方法其实就是声明了一个配置参数,方法名就是参数名,方法的返回值类型就是参数类型(只能是基本类型、Class、String、Enum)
  • 可以通过 default 来声明参数的默认值
  • 如果只有一个参数成员,一般将其命名为 value
  • 注解元素必须要有值,在定义注解元素时,经常使用 空字符串0 作为默认值
package AnnotationAndReflect.Annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Title: 测试自定义注解
 * @Description:
 * @author: QianYi
 * @date: 2020/10/19 - 22:04
 */
public class AnnotationTest2 {

    // 显示的定义值,不写就是使用默认值(default)
    @MyAnnotation01(name = "qy", age = 22, id = 1, schools = {"安徽大学"})
    public void test() {
    }

    //只有一个参数时,默认名字一般是value,可省略不写
    @MyAnnotation02("qy 666")
    public void test2() {
    }
}

/**
 * 自定义注解01
 */
@Target(value = {ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
@interface MyAnnotation01 {
    //参数类型、参数名、默认值
    String name() default "";

    int age() default 0;

    int id() default -1;

    String[] schools() default {"清华大学", "北京大学"};
}

/**
 * 自定义注解02
 */
@Target(value = {ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
@interface MyAnnotation02 {
    String value();
}

五、通过反射获取注解

/**
 * 表名注解
 */
@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
@interface TableQY {
    String value();
}

//-----------------------------------------------------------------------------------------

/**
 * 属性注解
 */
@Target(value = ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldQY {
    String columnName();// 列名
    String type();      // 类型
    int length();       // 长度
}

//------------------------------------------------------------------------------------------

@TableQY("db_student")
class Student {
    @FieldQY(columnName = "db_id", type = "int", length = 10)
    private int id;

    @FieldQY(columnName = "db_name", type = "String", length = 32)
    private String name;

    @FieldQY(columnName = "db_age", type = "int", length = 10)
    private int age;

    // get()、set()方法
    // toString()方法
}

//-------------------------------------------------------------------------------------------

public class GetAnnotationByReflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        // 通过反射获取类对象
        Class<?> clazz = Class.forName("AnnotationAndReflect.Annotation.Student");
        // 一、
        // 获取类注解
        Annotation[] clzzAnnotations = clazz.getAnnotations();
        System.out.println("类注解 : " + clzzAnnotations);
        // 获取类注解的value
        TableQY TableQYAnnotation = (TableQY) clazz.getAnnotation(TableQY.class);
        System.out.println("类注解value : " + TableQYAnnotation.value());

        // 二、
        // 获取类属性注解
        Field field = clazz.getDeclaredField("id");
        // 获取类属性注解的value
        FieldQY fieldAnnotation = field.getAnnotation(FieldQY.class);
        System.out.println("属性注解value : \t"
                           + fieldAnnotation.columnName() + "\t"
                           + fieldAnnotation.type() + "\t"
                           + fieldAnnotation.length());
    }
}

运行结果:
运行结果


参考信息

  • https://www.bilibili.com/video/BV1p4411P7V3 【狂神说Java】注解和反射
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值