黑马程序员-注解

---------------------- ASP.Net+Android+IOS开发</a>、 .Net培训、期待与您交流! ----------------------


基本Annotation

Java提供了三个基本Annotaion
@Override
@Deprecated
@SuppressWarnings

限定重写父类方法:@Override
@Override起到验证作用,被@Override修饰的方法是不是重写了父类方法,如果不是则报异常

/**
注解
*/

class Fruit
{
    public void foo()
    {
        System.out.println("水果的info方法...");
    }
}

class Apple extends Fruit
{
    //使用@Override指定下面方法必须重写父类方法
    @Override
    public void foo()
    {
        System.out.println("苹果重写水果的info方法...");
    }
}

标记已过时:@Deprecated
@Deprecated用于表示某个程序元素(类、方法等)已过时,当其他程序使用已过时的类、方法时,编译器将会给出警告

/**
注解
*/

class Apple
{
    //定义info方法已过时
    @Deprecated
    public void info()
    {
        System.out.println("Apple的info方法");
    }
}

class DeprecatedTest
{
    public static void main(String[] args)
    {
        //下面使用info方法时将会被编译器警告
        new Apple().info();
    }
}
抑制编译器警告:@SuppressWarnings
@SuppressWarnings指示被Annotation标识的程序元素(以及在该程序元素中的所有子元素)取消显示指定的编译器警告。@SuppressWarnings会一直作用于该程序元素的所有子元素
/**
注解
*/

//关闭整个类里的编译器警告
@SuppressWarnings(value = "unchecked")
class SuppressWarningsTest
{
    public static void main(String[] args)
    {
        //将不会有警告
        List<String> myList = new ArrayList();
    }
}

自定义Annotation

定义新的Annotation类型使用@interface关键字(在原有的interface关键字前增加@符号),自定义注解默认继承Annotation接口

/**
自定义注解
*/

public @interface MyTag
{
    //定义成员变量,形式类似抽象方法
    String name();
    int age();

    //为成员变量指定默认值
    String address() default "北京";
}
可以把元数据分为两类:
标记Annotation:一个没有成员定义的Annotation类型被称为标记,这种Annotation仅使用自身的存在与否来为我们提供信息
元数据Annotation:那些包含成员变量的Annotation


元注解(Meta Annotation)

JDK除了在java.lang下提供了3个基本Annotation之外,还在java.lang.annotation包下提供了4个Meta Annotation(元Annotation),这4个Annotation都是用于修饰其他Annotation定义


使用@Retention

@Retention用于修饰Annotation定义,用于指定该Annotation可以保存多长时间,@Retention包含一个RetentionPolicy枚举实例的变量,所以使用@Retention必须为该成员变量指定值

RetentionPolicy的实例有如下三个:
RetentionPolicy.SOURCE    //不编译进class文件
RetentionPolicy.CLASS    //编译器将把注解记录在class文件中,当运行Java程序时,JVM不再保留注解。这是默认值
RetentionPolicy.RUNTIME    //注解记录在class文件中,JVM也会保留注解,程序可以通过反射获取注解

//定义下面的Testable Annotation保留到运行时
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Testable{}

//或用如下的写法
//当Annotation的成员变量名为value时,可以在括号中直接指定值
@Retention(RetentionPolicy.RUNTIME)
public @interface Testable{}

使用@Target

用于修饰Annotation的定义,指定被修饰的Annotation能用于修饰哪些程序元素

@Target Annotation也包含一个名为value的ElementType枚举实例:
ElementType.TYPE    //可以修饰类、接口(包括注解类型)或枚举定义
ElementType.ANNOTATION_TYPE    //指定只能修饰Annotation
ElementType.CONSTRUCTOR    //只能修饰构造器
ElementType.FIELD    //只能修饰成员变量
ElementType.LOCAL_VARIABLE    //只能修饰局部变量
ElementType.METHOD    //只能修饰方法
ElementType.PACKAGE    //只能修饰包定义

/**
元Annotation,@Target
*/

@Target(ElementType.FIELD)
public @interface Demo
{

}

//接收的参数可以是一个数组
@Target({ElementType.Type, ElementType.Method})
public @interface Demo2
{

}

使用@Documented

@Documented用于指定被该元Annotation修饰的Annotation类将被javadoc工具提取成文档

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
//定义Testable Annotation将被javadoc工具提取
@Documented
public @interface Testable
{
}

使用@Inherited

@Inherited元Annotation指定被它修饰的Annotation将具有继承性
如果某个类使用了一个Test Annotation(定义该Annotation时使用了@inherited修饰)修饰,则其子类将自动具有Test注解


反射提取Annotation的信息

当一个Annotation类型被定义为运行时Annotation后,注解运行时才可见,只有通过反射才可以读取运行时Annotation

Class、Constructor、Field、Method、Package均实现了AnnotatedElement接口,实现了如下方法:
T getAnnotation(Class<T> annotationClass)    //返回该程序元素上存在的,指定类型的注解,如果该类型不存在,则返回null
Annotation[] getAnnotations()    //返回该程序元素上存在的所有注解
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)    //判断该程序元素上是否包含指定类型的注解

import java.lang.annotation.*;
/**
使用反射获取Annotation,必须保证要获取的注解是运行时注解
*/

//设置MyAnnotation为运行时注解
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation
{
    //定义成员
    String color();

    //带默认值的成员
    int num() default 23;

    //数组成员
    int[] arr();

    //枚举成员
    EnumTest enumAttribute() default EnumTest.Red;

    //注解成员
    anotherAnnotation anotherAnn() default @anotherAnnotation(age = 999);
}

@MyAnnotation(color = "Red", arr = {2, 3, 5, 5})
class AnnotationTest
{
    public static void main(String[] args)
    {    
        if(AnnotationTest.class.isAnnotationPresent(MyAnnotation.class))
        {
            MyAnnotation annotation = AnnotationTest.class.getAnnotation(MyAnnotation.class);
            System.out.println(annotation.color());
            System.out.println(annotation.arr().length);
            System.out.println(annotation.enumAttribute().nextLamp().name());
            System.out.println(annotation.anotherAnn().age());
        }
    }
}

//定义一个枚举
enum EnumTest
{
    Red(30)
    {
        public EnumTest nextLamp()
        {
            return Green;
        }
    }, 
    Green(45)
    {
        public EnumTest nextLamp()
        {
            return Yellow;
        }
    }, 
    Yellow(5)
    {
        public EnumTest nextLamp()
        {
            return Red;
        }
    };

    private int num = 0;

    //构造函数只能使用private,默认使用的就是private
    private EnumTest(int num)
    {
        this.num = num;
    }

    //抽象方法
    public abstract EnumTest nextLamp();
}

//定义一个注解
@interface anotherAnnotation
{
    int age();
}



---------------------- ASP.Net+Android+IOS开发</a>、 .Net培训、期待与您交流! ----------------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值