注解

作者: 我是许仙 | 来源:发表于2020-09-10 17:22 被阅读0次

作用**

jdk1.5以后出现的

  1. 编译检查

    @Override 注解 -在编译阶段检查方法是否继承自父类

  2. 编写文档

    javadoc 生成文档

  3. 代码分析 -jdk预定于的注解

    1. @override 检查方法是否继承父类

    ​ <img src="http://ww1.sinaimg.cn/large/006UamUGly1gilobcj5muj30l80ck0th.jpg" alt="image-20200909210239790.png" style="zoom:50%;" />

    <img src="http://ww1.sinaimg.cn/large/006UamUGly1gilobrbk30j30lk0bqjs3.jpg" alt="image-20200909210301542.png" style="zoom:50%;" />

    1. @Deprecate 当前方法已经废弃,但是可以使用
  ```java
   public void  add1() {
          //老的方法,不建议在使用。不能直接删除,需要给程序员提示
      }
  
      public void add2() {
          //新增的方法,希望替代老的方法
      }
  ```

  加入@Deprecate注解

  ```java
  @Deprecated 
  public void  add1() {
      //老的方法,不建议在使用。不能直接删除,需要给程序员提示
  }
  
  public void add2() {
      //新增的方法,希望替代老的方法
  }
  ```

  ![image-20200909210628025.png](https://img.haomeiwen.com/i9388376/d9b281f6e7c12c4a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 

  可以看到当调用被@Deprecated注解标识的方法的时候,idea工具会提示次方法已经废弃不建议使用,方法中有个-- 。但是方法最终还是可以使用的,只不过给程序员一个提示而已。
  1. @SuppressWarning 压制所有的警告
image-20200909211030827.png
可以看到这段代码中有很多的警告⚠️,但是程序照样可以运行。如果我不想看到这些警告怎么办呢?

在类中添加@SuppressWarning("all")方法。
image-20200909211247520.png

自定义注解

格式

//原注解
public @interface 注解名称 {
  //属性
}
//用@interface

自定义

public @interface Myan {
}

注解的本质

把上面的自定义注解经过javac编译 然后在javap反编译看一下

base) -bash-3.2$ javac Myan.java 
(base) -bash-3.2$ ls
Myan.class  Myan.java
(base) -bash-3.2$ javap Myan.class 
Compiled from "Myan.java"
public interface Myan extends java.lang.annotation.Annotation {
}

可以看到反编译之后是这段代码

public interface Myan extends java.lang.annotation.Annotation {
}

说明注解的本质是一个继承java.lang.annotation.Annotation的接口 ,既然他是接口那么他就会有属性常量和方法

<span style="color:red" >注意,方法的返回值只能是如下类型</span>

  1. 基本类型
  2. string类型
  3. 枚举类型
  4. 注解类型
  5. 以上类型的数组
public @interface Myan {

    //属性常量
    public String name = null;

    //方法
    public String getName();

    public int getAge();

    public ElementType enunType();

    public Myan2 getAn();

    public String[] names();

    public   @interface Myan2 {
    }

}

属性

为什么注解定义的方法通常都叫做属性?

image-20200909214402000.png

​ 当我们使用注解的时候,注解中定义的方法必须都要赋值。

public class Test1 {

    @Myan(getName = "1")
    public String test() {
        return "";
    }
    
}

而给方法赋值的写法特别像在对象中初始化属性。所以通过给注解中定义的方法叫做属性。

多种返回值的属性怎么赋值

public class Test1 {

    @Myan(getName = "1",getAge = 1,getAn = @Myan.Myan2,enunType = ElementType.METHOD,names = {"a","b"})
    public String test() {
        return "";
    }

}

分别给5种属性赋值。数组属性赋值需要{}

default关键字

定义注解使用 default关键字

public   @interface Myan2 {
    String value() default "my";
}
@Myan2
public String test() {
    return "";
}

当属性使用 default关键字初始化属性值的时候, 使用注解可以不设置属性的值。如果不设置使用默认值。

不使用【属性=值】的方式

public   @interface Myan2 {
    String value();
}
@Myan2("1")
public String test() {
    return "";
}

如果注解只有一个属性且属性的名字是value,那么可以直接赋值。不需要使用 key=value的方式

元注解

  1. @Target 表示当前注解可以生效的位置。值是ElementType枚举。常用的有

    1. TYPE可以声明在类上
    2. FIELD可以声明在类的属性中
    3. METHOD可以声明在方法中
    4. PARAMETER 参数
    5. CONSTRUCTOR构造器

    声明一个注解,定义注解只能用在方法上

    @Target(ElementType.METHOD)
    public @interface Myan3 {
    }
    
    image-20200910163804044.png

    如果用在方法上编译报错。

  2. @Retention 描述注解被保留的阶段。

    public enum RetentionPolicy {
        //编译阶段
        SOURCE,
        // 字节码阶段
        CLASS,
        //运行阶段  通常用这个
        RUNTIME
    }
    

    比如说 @SuppressWarnings只在编译阶段有效

    image-20200910164201466.png
  3. @Documented 代表可以生成文档

  4. **@Inherited **描述注解是否可以被子类继承

自定义注解使用案例

自定义一个注解,注解中有2个属性。获取类的全路径 与 获取方法名。通过获取注解中的属性生成一个对象。

定义注解

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

    //获取类名
    String getClassName();
    //获取方法名
    String getMethodName();
}

例子

@InvokeAnno(getClassName = "com.javaDemo.annotation.Test3",getMethodName = "log")
public class Test3 {

    public void log() {
        System.out.println("执行方法log----");
    }

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        //获取class类
        Class<Test3> test3Class = Test3.class;
        //通过反射获取类中的注解
        InvokeAnno annotation = test3Class.getAnnotation(InvokeAnno.class);
        //获取注解属性
        String className = annotation.getClassName();
        String methodName = annotation.getMethodName();
        //通过反射获取类
        Class<?> aClass = Class.forName(className);
        Object o = aClass.newInstance();
        //通过反射获取方法
        Method method = aClass.getMethod(methodName);
        //调用方法
        method.invoke(o);

    }
}

相关文章

  • 注解学习笔记

    什么是注解注解分类注解作用分类 元注解 Java内置注解 自定义注解自定义注解实现及使用编译时注解注解处理器注解处...

  • 注解与反射

    注解 声明一个注解类型 元注解 在定义注解时,注解类也能够使用其他的注解声明。对注解类型进行注解的注解类,我们称之...

  • 1.8 Java 注解annotation

    1.1 注解声明 Java注解Annotation,有声明注解和元注解 元注解:Java提供的元注解,所谓元注解就...

  • 注解的使用

    元注解 注解 注解本质就是接口: 元注解:修饰注解的注解 自定义注解 Text.java FruitName.ja...

  • 注解

    Java注解 注解 元注解 自定义注解 元注解:负责注解其他注解 共有4个标准的meta-annotation类型...

  • Spring高级应用之组合注解和元注解

    1.核心概念: 元注解:可以注解在其他注解上的注解;被注解的注解成为组合注解; 2.组合注解的定义步骤 定义组合注...

  • 2016.10.13-关于注解的自定义和注解的解析

    注解可以分为:1、标识性注解(没有成员变量) 2、注解 3、元注解(注解的注解) 1、注解的自定义 自定义注解的格...

  • 自定义注解

    注解分类 1、代码注解2、编译时注解3、运行时注解 注解范例 使用注解的类 注解解析类 注解实战 需求1、有一张用...

  • 【JAVA】注解

    元注解 用来定义、声明注解的注解。 @Inherited注解 使用此注解声明出来的自定义注解,在使用此自定义注解时...

  • Spring Boot常用注解

    注解速览 配置加载相关 Bean 声明注解 Bean 注入注解 SpringMVC 注解 MyBatis 注解 配...

网友评论

      本文标题:注解

      本文链接:https://www.haomeiwen.com/subject/rgipektx.html