java基础-注解

以下为本人的学习笔记

 

1.认识Annotation

  JDK1.5开始,java增加了对元数据(即类的组成单元数据)的支持,也就是(Annotation)注解,它是代码里做的特殊标记,这些标记可以在编译,类加载,运行时在不改变原有逻辑的情况下,被读取(通过反射来读取),并执行相应 的处理,通过使用Annotation,程序员可以在源文件中嵌入一些补充从信息。代码分析工具,开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。Annotation类似于修饰符一样被使用,可以用于包,类,构造方法,方法,成员变量,局部变量的声明。

  元数据可以说是一个属性,解释数据的数据。如一个属性age的值为18,那么这个解释18的字段age就是元数据。

  注解也可以说是一个描述信息,把信息再解析。

  注解的本质是标记,他所有的功能都依赖于对于这个注解解释性的代码,通常需要结合反射来编写解释下代码。

注意:

Annotation是一个接口

java.lang.Annotation接口

 

2.系统定义的Annotation

在JDK1.5之后,在系统中提供了三个Annotation,分别是:@Override(译:覆盖)、@Deprecated(译:已弃用)、@SuppressWarings。

@Override

表示验证当前的方法是否覆盖超类中的方法(即重写父类方法)。如果你一不小心拼写错误,或者方法签名对不上被覆盖的方法,编译器就会发出错误提示

@Deprecated

表示的是一个类或方法已经不再建议继续使用了,标记为已过时

@SuppressWarings

表示关闭不当的编译器警告信息

Annotation 说明
@SuppressWarings("unchecked") 未检查的转化,如集合没有指定类型
@SuppressWarings("unused") 未使用的变量
@SuppressWarings("resource") 有泛型未指定类型
@SuppressWarings("path") 在类路径,原文件路径中有不存在的路径
@SuppressWarings("deprecation") 使用了某些不赞成使用的类和方法
@SuppressWarings("fallthrough") switch语句执行到底没有break关键字
@SuppressWarings("serial") 某类实现Serializable但是没有定义serialVersionUID这个需要但是不必须的字段
@SuppressWarings("rawtypes") 没有传递带有泛型的参数
@SupperssWarings("all") 全部类型的警告(用这一条就够了)

 

3.自定义Annotation

注解应用三个步骤:

1)编写注解

2)在类上应用注解

3)对应用了注解的类进行反射操作的类

自定义Annotation的语法如下:

访问控制权限@interface Annotation 名称{}

@interface : 定义一个注解的关键字

例如:

public @interface MyAnnotation{}

//1.自定义注解
//表示该注解的作用范围在运行时存在
@Retention(RetentionPolicy.RUNTIME)
//用于生成文档
@Documented
//用于表示注解的应用范围(类型,方法,属性,构造器,参数,局部变量,包,Annotation)
@Target(ElementType.TYPE)
@Inherited//子类可继承
public @interface MyAnnotation{
    //定义变量,注意:变量后要加括号(),且调用此注解时必须设置变量名
    public String name();
    
    public int age() default 2;//给变量设置默认值
    
    public String[] like();//定义一个数组,调用此注解时变量名要含大括号{}
    
    public COlor color();//定义一个枚举类型的变量
    
}
​
public enum Color{
    RED,GREEN,BLUE;
}
//2.使用注解
@MyAnnotation(name="wan",like = {"金鱼","草鱼"},color = Color.RED)
public class Cat{
    private String name;
    private int age;
    public String[] like;
    private Color color;
    ...(构造方法,getter(),setter())
}
public class AnnotationDemo{
    /**
        反射来处理注解
    */
    @Test
    public void test2(){
        Class<Cat> catClass = Cat.class;
        //获取类上应用的指定注解
        MyAnnotation annotation = CatClass.getAnnotation(MyAnnotation.class);
        //获取注解上变量值
        String name = annotation.name();
        int age = annotation.age();
        Color color = annotation.color();
        String[] like = annotation.like();
        try{
            //通过反射实例化对象,调用对象的方法存储注解上的值
            Cat cat =catClass.newInstance();
            cat.setName(name);
            cat.setAge(age);
            cat.setLike(like);
            cat.setColor(color);
            System.out.println(cat);
        }catch(InstantiationException e){
            e.printStackTrace();
        }catch(IllegalAccessException e){
            e.printStackTrace();
        }
​
    }
    
    
    
}    

 

4.Retention和RetentionPolicy

Annotation要想决定其作用的范围,通过@Retention(译:保持)指定,而Retention指定的范围由RetentionPolicy(policy,译:方针,政策,原则)决定,RetentionPolicy指定了三种范围:

范围 说明
public static final RetentionPolicy SOURCE 在java源程序中存在(提供给编译器使用)
public static final RetentionPolicy CLASS 在java生成的class存在
public static final RetentionPolicy RUNTIEM 在java运行的时候存在(我们通常使用这个范围)

示例:

@Retention(value = RetentionPolicy.RUNTIME)

public @interface MyAnnotation{

public String name();

}

 

5.反射与Annotation

一个Annotation真正起作用,必须结合反射机制,在反射中提供了以下的操作方法:

java.lang.reflect.AccessibleObject(供虚拟机使用)

Method 说明
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) (present,译:目前,出现) 判断是否是指定的Annotation
public Annotation[] getAnnotations() 得到全部的Annotation
public Annotation getAnnotation(Annotation.class) 获取指定的Annotation

注解在目前而言最主流的应用就是代替配置文件,例如Spring、SpringBoot等,注解具有开发效率高,成本低的特点,缺点是耦合性高,不利于维护

 

6.@Documented注解

此注解表示的是文档化,可以在生成doc文档的时候添加注解,即生成文档时,注释一起生成

 

7.@Target注解

@Target注解(用来注释注解)表示的是一个Annotation的使用范围,例如:之前定义的MyAnnotation可以在任意的位置上使用(没有写这个注解,就所有地方可以使用)

范围 说明
public static final ElementType TYPE 只能在类或接口或枚举上使用
public static final ElementType FIELD 在成员变量中使用
public static final ElementType METHOD 在方法中使用
public static final ElementType PARAMETER 在参数上使用
public static final ElementType CONSTRUCTOR 在构造中使用
public static final ElementType LOCAL_VARIABLE 局部变量上使用
public static final ElementType ANNOTATION_TYPE 只能在Annotation中使用
public static final ElementType PACKAGE 只能在包中使用

 

8.@Inherited注解

@Inherited表示一个Annotation是否允许被其子类继承下来(使用时表示允许)

 

9.面试题:

1、什么是注解?以及它的作用?

   从 JDK 5.0 开始, Java 增加了对元数据(MetaData) 的支持, 也就是Annotation(注解)。

   Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理。

   Annotation 可以像修饰符一样被使用, 可用于修饰包, 类, 构造器, 方法, 成员变量, 参数, 局部变量的声明, 这些信息被保存在Annotation 的 “name=value” 对中。

 

2、JAVASE常用的注解?

@Override: 限定重写父类方法, 该注解只能用于方法;在编译期检测是否是重写的方法;

@Deprecated: 用于表示所修饰的元素(类, 方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择;

@SuppressWarnings: 抑制编译器警告;

 

3、怎么自定义注解?

1)、定义新的 Annotation 类型使用 @interface 关键字,自定义注解自动继承了java.lang.annotation.Annotation接口。

2)、Annotation 的成员变量在 Annotation 定义中以无参数方法的形式来声明。其方法名和返回值定义了该成员的名字和类型。我们称为配置参数。类型只能是八种基本数据类型、String类型、Class类型、enum类型、Annotation类型、以及所有类型的数组。

3)、我们自定义的注解,如果有成员变量,那么在使用的时候必须赋值;如果自定义的注解的成员变量,赋予了默认值,那么我们使用的时候可以赋值,也可以不赋值; 我们需要default来给注解的成员变量赋值

4)、如果只有一个参数成员,建议使用参数名为value;

5)、没有成员定义的 Annotation 称为标记; 包含成员变量的 Annotation 称为元数据 Annotation; 我们都可以称之为注解;

 

4、什么元注解,元注解有哪些,作用是什么?

   JDK 的元 Annotation 用于修饰其他 Annotation 定义;

   @Retention: 只能用于修饰一个 Annotation 定义, 用于指定该 Annotation 的生命周期, @Rentention 包含一个RetentionPolicy 类型的成员变量, 使用@Rentention 时必须为该 value 成员变量指定值: RetentionPolicy.SOURCE:在源文件中有效(即源文件保留),编译器直接丢弃这种策略的注释;

   RetentionPolicy.CLASS:在class文件中有效(即class保留),当运行 Java 程序时, JVM 不会保留注解。 这是默认值;

   RetentionPolicy.RUNTIME:在运行时有效(即运行时保留),当运行 Java 程序时, JVM 会保留注释。程序可以通过反射获取该注释。

   @Target: 用于修饰 Annotation 定义, 用于指定被修饰的 Annotation 能用于修饰哪些程序元素。 @Target 也包含一个名为 value 的成员变量。

   @Documented: 用于指定被该元 Annotation 修饰的 Annotation 类将被javadoc 工具提取成文档。默认情况下,javadoc是不包括注解的。

   @Inherited: 被它修饰的 Annotation 将具有继承性。

 

■免责申明
⒈ 本站是纯粹个人学习网站,与朋友交流共赏,不存在任何商业目的。
⒉ 本站利用了部分网络资源,版权归原作者及网站所有,如果您对本站所载文章及作品版权的归属存有异议,请立即通知我们,我们将在第一时间予以删除,同时向你表示歉意!

 

posted @ 2022-10-28 23:06  逝去の年华  阅读(92)  评论(0编辑  收藏  举报