10.1 java注解

Annotation

  1. 注解(Annotation)是从JDK5.0开始引入的新技术。
  2. 注解不是程序本身,可以对程序作出解释;注解可以在编译,类加载,运行时被读取,并执行相应的处理,以便于其他工具补充信息或者进行部署。
  3. 注解可以对package(包),class(类),method(方法),field(属性)等使用,相当于给它们添加了额外的辅助信息。

内置注解

  1. 限定父类重写方法:@Override
    当子类重写父类方法时,子类可以加上这个注解,确保子类确实重写了父类的方法。
  2. 标示已过时:@Deprecated
    这个注解用于表示某个程序元素类,方法等已过时,当其他程序使用已过时的类或方法时编译器会给出警告。
  3. 抑制编译器警告:@SuppressWarnings
    被该注解修饰的元素以及该元素的所有子元素取消显示编译器警告,即用来抑制编译时的警告信息。
    @SuppressWarnings注解需要添加一个参数才能使用,这些参数值是已经定义好的,可直接使用。
    示例:@SuppressWarnings("unchecked")
    @SuppressWarnings(value={"unchecked", "deprecation"})
    参数如下:
参数说明
deprecation使用了过时的类或方法的警告
unchecked执行了未检查的转换时的警告,如使用集合时未指定泛型
fallthrough当在switch语句使用时发生case穿透
path在类路径、源文件路径中有不存在路径的警告
serial当在可序列化的类上缺少serialVersionUID定义时的警告
finally任何finally子句不能完成时的警告
all关于以上所有情况的警告

元注解

      修饰其他注解的注解叫做元注解。

  1. @Target
    使用@Target可以定义Annotation能够被应用于源码的哪些位置:
修饰范围取值
类或接口ElementType.TYPE
字段ElementType.FIELD
方法ElementType.METHOD
构造方法ElementType.CONSTRUCTOR
方法参数ElementType.PARAMETER
局部变量ElementType.LOCAL_VARIABLE
ElementType.PACKAGE

@Target注解的源代码

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    ElementType[] value();
}

其中 value() 是参数名,ElementType[ ]是参数类型,是一个数组,可有多个值。
即使用方式为

@Target(value=ElementType.METHOD)@Target(value={ElementType.METHOD,ElementType.TYPE})
  1. @Retention
    @Retention用来表示需要在什么级别保存该注释信息,用于描绘注解的生命周期。
取值RetentionPolicy作用
SOURCE在源文件中有效(源文件保留注解)
CLASS在class文件中有效(class保留)
RUNTIME在运行时有效,此注解可以被反射机制读取

@Retention注解的源代码

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}

通常我们自定义的Annotation使用Retention修饰时,值都为RUNTIME。

  1. @Repeatable
    使用@Repeatable这个元注解可以定义Annotation是否可重复,经过@Repeatable修饰后,在某个类型声明处,就可以添加多个此注解;此元注解应用不是很广泛。
  2. @Inherited
    使用@Inherited定义子类是否可继承父类定义的Annotation。@Inherited仅针对@Target(ElementType.TYPE)类型的annotation有效,并且仅针对class的继承,对interface的继承无效。

自定义注解

  • 第一步,用@interface定义注解;
  • 第二步,添加参数、默认值。把最常用的参数定义为value(),推荐所有参数都尽量设置默认值。
  • 第三步,用元注解配置注解。必须设置@Target来指定Annotation可以应用的范围;必须设置@Retention,属性值最好为RetentionPolicy.RUNTIME便于运行期读取该Annotation。

示例

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

@Target(value={ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DxtAnnotation {
    String value() default "";
    int age() default 0;
    int id() default -1;	//默认设为-1
}

使用时

@DxtAnnotation(value="dxt", age=18, id=111, schools={"蓝翔", "新东方"})
public void test(){	
}

使用时如果注解只有一个参数value()时,则可以直接在括号中添加值,比如:

@DxtAnnotation("dxt")
public void test(){	
}

反射获取注解

  1. 有一个Student类,使用注解去修饰这个类和这个类中的属性。注解中的信息就是修饰对应数据的,我们可以通过获取对应注解,获取对应数据的更多信息。
  2. 注解定义中,@Retention的值必须设置为RetentionPolicy.RUNTIME,因为反射就是发生在程序运行中。
    注解1(修饰类)
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 为Student类自定义一个注解
 * 为类指定一个数据库中的表名,存储到value中
 * @author dxt
 *
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
	String value() default "";
}

注解2(修饰类中的属性)

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 为Student中的属性自定义一个注解
 * 说明属性对应数据库表中的字段信息
 * @author dxt
 *
 */
@Target(value = ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Field {
	String columnName();	//列名
	String type();		//类型
	int length();		//长度
}

Student类

/**
 * student类
 * @author dxt
 *
 */
@Table(value = "tb_student")
public class Student {
	@Field(columnName="id", type="int", length=10)
	private int id;
	@Field(columnName="sname", type="varchar", length=10)
	private String name;
	@Field(columnName="age", type="int", length=3)
	private int age;
	
	public Student(){
	}
	public Student(int id, String name, int age){
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	
	public void setId(int id){
		this.id = id;
	}
	public int getId(){
		return this.id;
	}
	public void setName(String name){
		this.name = name;
	}
	public String getName(){
		return this.name;
	}
	public void setAge(int age){
		this.age = age;
	}
	public int getAge(){
		return this.age;
	}
}

反射获取注解

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

/**
 * 使用反射机制读取注解的信息,模拟处理竹节信息的流程
 * @author dxt
 *
 */
public class Demo03 {
	public static void main(String[] args){
		try {
			Class c = Class.forName("dxt.annotation.Student");
			//获取类的所有注解
			Annotation[] annos = c.getAnnotations();
			for(Annotation a : annos){
				System.out.println(a);
			}
			//依据注解类,直接获取指定注解
			Table table = (Table)c.getAnnotation(Table.class);
			System.out.println(table.value());
			
			//获取类的属性的注解
			Field f = c.getDeclaredField("name");
			//教训:怎么可以把类名设置为 Field呢
			dxt.annotation.Field fa = f.getAnnotation(dxt.annotation.Field.class);
			System.out.println(fa.columnName()+"--"+fa.type()+"--"+fa.length());
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值