注解

    在Java中,注解就是给程序添加一些信息,用字符@开头,这些信息用于修饰它后面紧挨着的其他代码元素,比如类、接口、字段、方法中的参数、构造方法等。注解可以被编译器、程序运行时和其他工具使用,用于增强或修改程序的行为。
常用的内置注解

  1. 创建注解:
        首先看看什么是元注解,元注解是指注解的注解(用于定义注解本身),包括@Retention、@Target、@Document、@Inherited四种。
            1. @Retention:定义注解的保留策略。
            2. @Target:定义注解的作用目标。
            3. @Document:说明该注解将被包含在javadoc中。
            4. @Inherited:说明子类可以继承父类中的该注解。
        下面看看@Override的定义:
@Target(ElementType.METHOD)
@Retention(RententionPolicy.SOURCE)
public @interface Override{
}

    定义注解使用@interface,@Target表示注解的目标,@Override的目标是方法(ElementType.METHOD)。ElementType是一个枚举,主要可选值有:
        TYPE:表示类、接口(包括注解),或者枚举声明;
        FIELD:字段,包括枚举常量;
        METHOD:方法;
        PARAMETER:方法中的参数;
        CONSTRUCTOR:构造方法;
        LOCAL_VARIABLE:本地方法;
        MODULE:模块(Java9引入的)。
    目标可以有多个,用{}表示,如果没有声明@Target,默认为适用于所有类型。
    @Retention表示注解信息保留到什么时候,取值只能有一个,类型为RetentionPolicy,它是一个枚举,有三个取值。
        @SOURCE:只在源代码中保留,编译器将代码编译为字节码文件后就会丢掉。
        @CLASS:保留到字节码文件中,但Java虚拟机将class文件加载到内存时不一定会在内存中保留。
        @RUNTIME:一直保留到运行时。
    如果没有声明@Rentention,则默认为CLASS。@Override是给编译器用的,所以@Retention都是RetentionPolicy.SOURCE。
    可以为注解定义一些参数,定义的方式是在注解内定义一些方法,比如@SupperessWarnings内定义的方法value,返回值类型表示参数的类型,这里是String[]。使用@SuppressWarnings时必须给value提供值,比如:

//Java7中@SuppressWarning的定义
@Target({TYPE,FILED,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings{
	String[] values;
}
//@SuppressWarnings注解的使用
@SuppressWarnings(value={"deprecation","unused"})

    当只有一个参数时,且名称为value时,提供参数值时可以省略"value="。注解内参数的类型不是什么都可以的,合法的类型有基本类型、String、Class、枚举、注解,以及这些类型的数组。
    参数定义时可以使用default指定一个默认值,比如,Guice中Inject注解的定义:

@Target({METHOD,CONSTRUCTOR,FIELD})
@Retention(RUNTIME)
@Documented	//表示注解信息包含到生成的文档中
public @interface Inject{
	boolean optional() default fasle;
}

    它有一个参数optional,默认值为fasle。如果类型为String,默认值可以为"",但不能为null。如果定义了参数并且没有提供默认值。在使用注解时必须提供具体的值,不能为null。
    与接口和类不同,注解不能继承。不过注解有一个与继承有关的元注解@Inherited,说明子类可以继承父类中的该注解,看个列子:

public class InheritDemo{
	@Inherited
	@Retention(RetentionPolicy.RUNTIME)
	static @interface Test{
	}
	@Test
	static class Base{
	}
	static class Child extends Bae{
	}
	public static void main(String[] args){
		System.out.println(Child.class.isAnnotationPresent(Test.class));
	}
}

    Test是一个注解,类Base有该注解,Child继承了Base但没有声明该注解。main方法检查Child类是否有Test注解,输出为true,这是因为Test有注解@Inherited,如果去掉,输出会变为false。
2. 查看注解的信息
    通过反射相关类中的与注解有关的方法,这里汇总说明下,Class、Field、Method、Constructor中都有如下方法:

//获取所有的注解
public Annotation[] getAnnotations()
//获取所有本元素上之直接声明的主键,忽略inherited来的
public Annotation[] getDeclaredAnnotations()
//获取指定类型的注解,没有返回null
public <A extens Annotation> A getAnnotation(Class<A> annotationClass)
//判断是否有指定类型的注解
public boolean isAnnotationPresent(Class<? extens Annotation> annotationType()

    Annotation是一个注解,它表示注解,具体定义为:

public interface Annotation{
	boolean equals(Object obj);
	int hashCode();
	String toString();
	//返回真正的注解类型
	class<? extens Annotation> annotationType();
}

    实际上,内部实现时,所有的注解类型都是拓展的Annnotation。
    对于Method和Contructor,它们都有方法参数,而参数也可以有注解,所以它们都有如下方法:

public Annotation[][] getParamterAnnotations()

    返回值是一个二维数组,每个参数对应一个一维数组。1


  1. Java编程的逻辑 ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值