Annotation

一:简介

使用注释,可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充的信息。Annotation可以用来修饰类、属性、方法,而且Annotation不影响程序运行,无论是否使用Annotation,代码都可以正常执行。


二:各个Annotation使用

1、@Override

表示这个方法是覆写父类中的方法:

范例1:

package haizhu.com;

class Person{
	public String getInfo(){
		return "这是一个Person类";
	}
}

class Student extends Person{
	@Override
	public String getInfo(){
		return "这是一个Student类";
	}
}
public class AnnotationDemo01 {
	public static void main(String[] args) {
		Person per = new Student();
		System.out.println(per.getInfo());
	}

}

如果声明了@Override,则使用IDE进行编辑的时候,如果继承的这个类中没有这个歌方法,就会进行出错提醒,如果使用记事本编辑,则会在编译的时候进行出错提醒。


2、@Deprecated

表示这个方法不建议使用:

范例2:

package haizhu.com;

class Person{
	@Deprecated
	public String getInfo(){
		return "这是一个Person类";
	}
}

public class AnnotationDemo02 {
	public static void main(String[] args) {
		Person per = new Person();
		System.out.println(per.getInfo());
	}

}
在使用Person的实例调用getInfo()方法的时候,如果使用IDE,则调用的时候就会出现一个中间的横线提醒这个方法不建议使用,如果使用记事本,会在编译的时候使用。除了在方法中可以声明为@Deprecated,在类中也可以声明:

范例3:

package haizhu.com;

@Deprecated
class Person{
	public String getInfo(){
		return "这是一个Person类";
	}
}

public class AnnotationDemo03 {
	public static void main(String[] args) {
		Person per = new Person();
		System.out.println(per.getInfo());
	}

}
同样,在IDE和编译的时候都会出现警告信息,因为Person类不建议使用。


3、@SuppressWarnings

用来压制警告:

范例4:

package haizhu.com;

class Demo<T>{
	private T var;
	public T getVar() {
		return var;
	}
	public void setVar(T var) {
		this.var = var;
	}
}

public class AnnotationDemo04 {
	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		Demo d = new Demo();
		d.setVar("海竹");
		System.out.println("内容:"+d.getVar());
	}

}
上面是用来压制一个泛型的警告信息。可以同时压制多条警告信息,如下所示:
范例5:

package haizhu.com;

@Deprecated
class Demo<T>{
	private T var;
	public T getVar() {
		return var;
	}
	public void setVar(T var) {
		this.var = var;
	}
}

public class AnnotationDemo05 {
	@SuppressWarnings({"unchecked","deprecation"})
	public static void main(String[] args) {
		Demo d = new Demo();
		d.setVar("海竹");
		System.out.println("内容:"+d.getVar());
	}

}
另外一种写法:

范例6:

package haizhu.com;

@Deprecated
class Demo<T>{
	private T var;
	public T getVar() {
		return var;
	}
	public void setVar(T var) {
		this.var = var;
	}
}

public class AnnotationDemo06 {
	@SuppressWarnings(value = {"unchecked","deprecation"})							// 将这个内容赋给 value
	public static void main(String[] args) {
		Demo d = new Demo();
		d.setVar("海竹");
		System.out.println("内容:"+d.getVar());
	}

}

三:自定义Annotation

1、定义简单的Annotation

范例7:

package haizhu.com;

public @interface MyAnnotation {											// @interface 就表示这个 annotation 继承了 java.lang.annotation.Annotation 接口
	public String value();													// 接收设置的内容
}

@MyAnnotation(value = "海竹")													// 使用自定义的 Annotation
class Demo{
}

2、向Annotation传递多个值:传递多个属性和一个属性接收多个值

也可以在Annotation中设置多个属性:

范例8:

package haizhu.com;

public @interface MyAnnotation {
	public String key();
	public String value();													// 接收设置的内容
}

@MyAnnotation(key = "haizhu",value = "海竹")											// 多个属性
class Demo{
}
一个属性接收多个值:
范例9:

package haizhu.com;

public @interface MyAnnotation {
	public String[] value();													// 用数组接收内容
}

@MyAnnotation(value = {"海竹","向北西行"})												// 传递一个数组
class Demo{
}
3、默认值

如果在一个定义好的Annotation中已经定义好了若干个属性,但是在使用Annotation时没有指定具体的内容,则在编译的时候也会出现错误,所以,在定义Annotation的时候,最好定义好默认值:

范例10:

package haizhu.com;

public @interface MyAnnotation {
	public String value() default "海竹";											// 设置默认值
}

@MyAnnotation																	// 可以不用传递
class Demo{
}
4、使用枚举限制设置的内容:

范例11:

package haizhu.com;

public enum MyEnumName {
	海竹,向北西行,程序员;
}
package haizhu.com;

public @interface MyAnnotation {
	public MyEnumName value() default MyEnumName.海竹;							// 使用枚举数据
}
@MyAnnotation(value = MyEnumName.向北西行)
class Demo{
}
5、@Retention 、RetentionPolicy 、@Documented 、@Inherited 、@Target
范例12:

package haizhu.com;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;

@Documented
@Inherited
@Retention(value=RetentionPolicy.RUNTIME)
@Target(value=ElementType.TYPE)
public @interface Retention{
	RetentionPolicy value();
}
@Retention:表示注释作用的范围,变量RetentionPolicy 有三个可选项:SOURCE、CLASS、RUNTIME

@Documented:

@Target:表示注释作用的类型,是作用在普通方法、构造方法还是作用在类上,变量ElementType 

@Inherited:用来标注一个父类的注释是否可以被子类继承,如果需要被继承,加上@Inherited 即可


四:Annotation 结合反射的应用

1、取得注释

通过反射,取得一个方法中所有的注释:

范例13:

package haizhu.com;

public class ManyAnnotation{
	@SuppressWarnings(value = { "unchecked" })
	@Deprecated
	@Override
	public String toString(){												//在这个方法上,有三个注释	
		return "我有很多注释。。。。";
	}
}
package haizhu.com;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class GetAnnotationByReflect {
	public static void main(String[] args) throws Exception{
		Class<?> c = Class.forName("haizhu.com.ManyAnnotation");				//取得class类实例
		Method m = c.getMethod("toString");										//取得"toString"方法
		Annotation an[] = m.getAnnotations();									//取得这个方法的所有注释
		for(Annotation a : an){
			System.out.println(a);												//遍历,打印
		}
	}

}
结果:

@java.lang.Deprecated()
为什么有三个注释,结果只取到了一个呢?因为只有一个注释默认的是“RUNTIME”类型,能够取得到,另外两个取不到。

2、取得注释的内容

范例14:

package haizhu.com;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(value=RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	public String key() default "haizhu";
	public String value() default "海竹";
}
package haizhu.com;

public class ManyAnnotation{
	@SuppressWarnings(value = { "unchecked" })
	@Deprecated
	@Override
	@MyAnnotation(key="hello",value="world")
	public String toString(){
		return "我有很多注释。。。。";
	}
}
package haizhu.com;

import java.lang.reflect.Method;

public class GetAnnotationContentByReflect {
	public static void main(String[] args) throws Exception{
		Class<?> c = Class.forName("haizhu.com.ManyAnnotation");
		Method m = c.getMethod("toString");
		if(m.isAnnotationPresent(MyAnnotation.class)){
			MyAnnotation ma = m.getAnnotation(MyAnnotation.class);
			String key = ma.key();
			String value = ma.value();
			System.out.println("key值:"+key+"\tvalue值:"+value);
		}
	}
}

结果:

key值:hello	value值:world
使用isAnnotationPresent 判断一个类是否是注释类,然后取得这个注释的key值和value值。





















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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值