注解

如果说注释是给人看的提示信息,则注解是给程序看的提示信息

1.java中提供了很多自带的注解,其中常见的有:
@Override: 限定重写父类方法, 该注解只能用于方法
@Deprecated: 用于表示某个程序元素(类, 方法等)已过时
@SuppressWarnings: 抑制编译器警告. 

常用来替代配置文件

2.自定义注解:
通过 @interface 关键字可以自定义一个注解,自定义一个注解的过程和定义一个接口的过程类似
在注解类中也可以为注解声明一个或多个属性,声明注解属性的过程就像在为一个接口定义方法一样
String name();
String name2() default "xxx";//也可以使用default 关键字为属性设定默认值
String value();//value属性是一个特殊的属性,如果整个注解中只有一个属性,并且这个属性的名字叫做value,则在使用这个注解时,属性的名字可以省略,直接给value的值就可以了
注解的属性可以是如下类型:
String、基本数据类型、枚举、Class 、其它注解类型、以上数据类型相应一维数组

在定义注解的过程中还可以用java中提供的元注解修饰我们自己定义的注解,所谓的元注解指的是sun提供用来描述注解的基本特性的一些注解
(1)!!@Retention:只能用于修饰一个 Annotation 定义, 用于指定该 Annotation 可以保留的域 ,@Override注解属于这种类型;
RetentionPolicy.SOURCE: 表明被修饰的注解是源码级别的注解,只在源码.java文件中存在,在编译器编译的过程中,这个注解被丢弃掉,向这种注解通常是给编译器使用的注解

RetentionPolicy.CLASS: 表明被修饰的注解是字节码级别的注解,这个注解在.java源码和.class字节码文件中存在.在.class文件被加载到内存中时,这个注解被丢弃.除了可以给编译器使用还可以在虚拟机加载类的过程中使用.


RetentionPolicy.RUNTIME:表明被被修的注解是运行阶段的注解,这个注解信息在.java源码.class字节码文件以及程序运行阶段都存在.这样的注解在运行阶段也存在,通常用来通过反射获取,使程序根据注解进行不同的操作.


(2)!!@Target:
指定注解用于修饰类的哪个成员. @Target 包含了一个名为 value,类型为ElementType的成员变量。
ElementType.TYPE, 申明该注解用于类上;
ElementType.METHOD, 用于方法上;
ElementType.FIELD  用于类的属性上;

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

(4)@Inherited: 
被它修饰的 Annotation 将具有继承性.如果某个类使用了被 @Inherited 修饰的 Annotation, 则其子类将自动具有该注解

4.反射注解:
检查类/方法/类变量/构造方法是否有具体的注解,获取注解,根据注解来执行不同的操作
AnnotatedElement定义了如下方法,而Class/Method/Field/Constructor都实现了这个接口,所以通过这些对象都可以调用如下方法在类/方法/成员变量/构造器上获取或判断是否包含指定的注解
(1)<T extends Annotation> T  getAnnotation(Class<T> annotationClass) 
 如果存在该元素的指定类型的注解,则返回这些注解,否则返回 null。 
 获取了该注解对象以后,就可以获取属性值;
 
(2)Annotation[] getAnnotations() 
 返回此元素上存在的所有注解。 
 
(3)Annotation[] getDeclaredAnnotations() 
 返回直接存在于此元素上的所有注解。
 
(4)boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) 
 如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。 

示例代码:

package com.oterman.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 申明一个注解;
 * @author 大蘑菇
 *
 */
@Retention(RetentionPolicy.RUNTIME)//指定该注解保留到运行时;
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})//表明该注解可以用在类上,方法上,属性上;
@interface MyAnnotation{
	public String attribute();//定义属性;
//	public String value();//比较特殊的属性,如果只有它时,在使用时可以直接赋值;
}


/**
 * 演示注解的使用;
 * @author 大蘑菇
 *
 */

//给类加注解;
@MyAnnotation(attribute="in class!")
class Person{
	//给属性加注解;
	@MyAnnotation(attribute="in field!")
	public String name=null;
	//给方法加注解;
	@MyAnnotation(attribute="in method!")
	public void eat(){
	}
}

/**
 * 测试注解的使用;
 * @author 大蘑菇
 *
 */
public class AnnotationDemo {
	public static void main(String[] args) throws Exception, NoSuchMethodException {
		Class clazz=Person.class;
		//获取类上的注解对象;
		MyAnnotation an1=(MyAnnotation) clazz.getAnnotation(MyAnnotation.class);
		//获取属性值;
		System.out.println(an1.attribute());//in class!
		
		//判断方法上是否有某个注解;
		Method method=clazz.getMethod("eat");
		boolean b=method.isAnnotationPresent(MyAnnotation.class);
		System.out.println(b);//true
		
		//获取方法注解的属性值;
		MyAnnotation an2=method.getAnnotation(MyAnnotation.class);
		System.out.println(an2.attribute());//in method!
		
		//获取类属性上的注解的属性值;
		Field field=clazz.getField("name");
		MyAnnotation an3=field.getAnnotation(MyAnnotation.class);
		System.out.println(an3.attribute());//in field!
		
	}

}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值