注解

注解

  1. 定义: 注解是可以在源码层次上进行操作,或者可以处理编译器在其中放置了注解的类文件
  2. java对有无注解的代码会生成相同的虚拟机指令,但是添加注释可以有利于我们后期开发与使用
  3. 注解使用时以** @ **开头
public class test01 {
    public static final Logger LOGGER =  LoggerFactory.getLogger(test01.class);
//@Test  这个注解是使一个方法变成一个测试方法,使得可以独立运行,同时需要注意这个注解需要在适当工具的辅助下才可以使有
    @Test
    public void  test() throws Exception {
        LOGGER.error("error");
        LOGGER.warn("warn");
        LOGGER.info("info");
        LOGGER.debug("debug");
        LOGGER.trace("trace");
    }
}


// @SuppressWarnings("") 在类的上方是压制整个类的警告,在方法上时压制方法的警告
// 如果你使用 IDEA 你会发现当你吧这条语句注释后,a会发出警告
public class Test1 {
    @SuppressWarnings("看注释")
    public static void main(String[] args) {
        int a;
    }
}

//@Override 这个注解的意思是覆盖父类的方法,同时也起到了一定的检查作用
public class Test1 {
    @Override
    public String toString() {
        return "Test1{}";
    }
}


//@Deprecated 这个注解的意思是该方法已废除,但是该方法仍然可以使用
public class Test1 {
    public static void main(String[] args) {
        f();
    }
    @Deprecated
    public static void f()
    {
    }
}

注释:
SuppressWarnings(“链接”)

注解接口

//注解的生成方式
@interface 注解名{
    类型名  名称(); //注解元素的类型:基本类型  String  Class  enum类型  注解类型   
}

使用方法:

public class HelloWord {
    @My(value = "",name = "")// 进行注解中的数据赋值 看下方
    static <T> void f1(List<T> list)
    {
        T t = list.get(0);
        System.out.println("f1");
        System.out.println(t.getClass().getSimpleName());
    }
}

//元注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface My{
    String value() default ""; // default 生成一个默认值,
    // 需要注意的是 默认值并不是和注解存储在一起而是动态计算的,当我们重新修改了默认值后,重新编译此注解,则所有使用该注解的默认值都会发生修改
    String name() default "";
}

注解中的元素赋值:
赋值时的顺序无所谓,赋值格式: “”名字 = 数据”;
当我们的注解中只有一个元素时,将该注解的名称设为: value(); 这样在使用该注解对其中的数据赋值时,可以不用写名称,只有在注解中只有一个数据时并且数据声明为value才可以省略,否则会报错

其他的一些注解

@NonNull 在使用的时候,放在变量前面,告诉编译器该变量的类型不为空
@ReadOnly 使用在方法的参数,标明该参数在方法中不会修改

元注解

元注解是用来注解其他注解的,java定义四个meta-annotation,他们被用来提供对其他的annation类型做说明,这些类可以在java.lang.annation包中可以找到{@Target, @Retention, @Documented, @inherited }
@Target 被用来描述注解的使用范围(即可以使用在什么地方 )
@Retention 表示需要在什么级别保存信息,描述注解的生命周期 级别大小为:(SOURCE < CLASS < RUNTIME)一般选择最后一个
@Documented 说明注解被包含在 javadoc 中
@Inherited 说明子类可以继承父类的该注解

//括号内的值 进行源码追踪就可以知道
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface MyAnnation{
        String name();
        int id();
        int n();
}

容器注解

在JavaSE8,以后,将同种注解多次应用于某一项是合法的,对于重复注解的实现这来说需要提供一个容器注解,它可以将这些注解存储到一个数组中

public class HelloWord {
    @Test_Classe(
        { @Test_Class(name = "1次", exacpet = "1次"),
        @Test_Class(name = "2次", exacpet = "2次"),
        @Test_Class(name = "3次", exacpet = "3次")}
    )
    public static   void f( Integer  a)
   {
       a = 20;

   }
}



/**
 * @author Lenovo
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Test_Class{
    String name();
    String exacpet();
}

/**
 * 容器
 * @author Lenovo
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Test_Classe {
    Test_Class[] value();
}

使用反射获取注解

package com.company;

import java.lang.annotation.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author Lenovo
 * @version 1.0
 * @Date 2021/9/18 21:13
 */
@Mysql(value = "mysql",name = "hello")
public class Student extends A{
    @Mysql_student(row_name = "name", Type = "VarChar",row = 1)
    private String name;
    @Mysql_student(row_name = "id", Type = "long",row = 2)
    private long id;
    @Mysql_student(row_name = "Grade", Type = "int",row = 3)
    private int Grade;


    public Student(String name, long id, int grade) {
        this.name = name;
        this.id = id;
        Grade = grade;
    }
    @Test_Classe({
            @Test_Class(name = "1ci", exacpet = "1ci"),
            @Test_Class(name = "1ci", exacpet = "1ci"),
            @Test_Class(name = "3ci", exacpet = "3ci")}
    )
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", Grade=" + Grade +
                '}';
    }

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        final Class<?> c1 = Class.forName("com.company.Student");

        // getAnnotations 获取作用域该项的所有注解包括继承来的注解
        // @com.company.parent(10)
        //@com.company.Mysql(value="mysql", name="hello")
        var annotations = c1.getAnnotations();
        for (int i = 0; i < annotations.length; i++) {
            System.out.println(annotations[i]);
        }
        // getAnnotations 获取作用域该项的所有注解不包括继承来的注解
        // @com.company.Mysql(value="mysql", name="hello")
        var declaredAnnotations = c1.getDeclaredAnnotations();
        System.out.println(Arrays.toString(declaredAnnotations));

        //getAnnotation 获得给定类型的注解
        //mysql
        //hello
        var annotation = c1.getAnnotation(Mysql.class);
        System.out.println(annotation.value());
        System.out.println(annotation.name());

        // 获得类指定的注解 -- 域
        //[@com.company.Mysql_student(row_name="name", Type="VarChar", row=1)]
        //name
        //1
        //VarChar
        Field name = c1.getDeclaredField("name");
        var annotations1 = name.getAnnotations();
        System.out.println(Arrays.toString(annotations1));

        var annotation1 = name.getAnnotation(Mysql_student.class);
        System.out.println(annotation1.row_name());
        System.out.println(annotation1.row());
        System.out.println(annotation1.Type());

        //判断给定项是否有该注解
        //true
        //true
        //true
        //false
        System.out.println(c1.isAnnotationPresent(Mysql.class));
        System.out.println(c1.isAnnotationPresent(parent.class));
        System.out.println(name.isAnnotationPresent(Mysql_student.class));
        System.out.println(name.isAnnotationPresent(parent.class));


         获得类指定的注解 -- 方法
        //[@com.company.Test_Classe({@com.company.Test_Class(name="1ci", exacpet="1ci"),
        // @com.company.Test_Class(name="1ci", exacpet="1ci"),
        // @com.company.Test_Class(name="3ci", exacpet="3ci")})]
        Method toString1 = c1.getDeclaredMethod("toString");
        var annotations2 = toString1.getAnnotations();
        System.out.println(Arrays.toString(annotations2));
        //使用容器时需要注意使用getAnnotationsByType 返回一个数组
        //[@com.company.Test_Classe({@com.company.Test_Class(name="1ci", exacpet="1ci"),
        // @com.company.Test_Class(name="1ci", exacpet="1ci"),
        // @com.company.Test_Class(name="3ci", exacpet="3ci")})]
        var annotation3 = toString1.getAnnotationsByType(Test_Classe.class);
        System.out.println(Arrays.toString(annotation3));
        //@com.company.Test_Classe({@com.company.Test_Class(name="1ci", exacpet="1ci"),
        // @com.company.Test_Class(name="1ci", exacpet="1ci"),
        // @com.company.Test_Class(name="3ci", exacpet="3ci")})
        Annotation annotation6 = toString1.getAnnotation(Test_Classe.class);
        System.out.println(annotation6);
        //null
        Annotation annotation5 = toString1.getAnnotation(Test_Class.class);
        System.out.println(annotation5);


    }
}

@parent(10)
class A { }
/**
 * @author Lenovo
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@interface parent {
    int value();
}
/**
 * @author Lenovo
 */
@Target(ElementType.TYPE) // 描述注解使用范围
@Retention(RetentionPolicy.RUNTIME) // 描述注解的生命周期
@Documented()// 该注解将被包含在javadoc中
@Inherited // 子类可以继承父类的该注解
@interface Mysql {
    String value();
    String name();
}

/**
 * @author Lenovo
 */

@Target(ElementType.FIELD) // 描述注解使用范围
@Retention(RetentionPolicy.RUNTIME) // 描述注解的生命周期
@Documented()// 该注解将被包含在javadoc中
@Inherited // 子类可以继承父类的该注解
@interface Mysql_student {
    String row_name();
    String Type();
    int row();
}
/**
 * @author Lenovo
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Test_Class{
    String name();
    String exacpet();
}

/**
 * 容器
 * @author Lenovo
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Test_Classe {
    Test_Class[] value();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值