黑马程序员---JDK1.5新特性——注解(重点)

本文深入介绍了Java注解的基本概念、注解的定义及其各种属性,同时涵盖了如何利用反射技术操作注解等内容。

------- Java、.NetAndroid培训期待与您交流!------- 

声明:注解、泛型、反射和代理非常重要

1Java 提供的三个基本注解和四种常见注解

  (1) @SuppressWarings 抑制编译器警告

       如调用 new Date().getDate(); 编译时发出警告:@SuppressWarings ("deprecated"); 语句过时警告。

  (2) @Deprecated :过时地

       在一个定义好的方法的头上加上该注解语句,表示该方法过时了。

  (3) @Override :重写/覆盖/复写

  (4) 四种常见注解讲解

        @Retention 元注解:有三种取值(RetentionPolicy.SOURCE, RetentionPolicy.CLASS, RetentionPolicy.RUNTIME),分别对应:Java源文件,class文件,内存中的字节码。

        @Target 元注解:指定注解用于修饰类的哪个成员。Target注解中的 value 有八种值,分别是:

                ElementType.ANNOTATION_TYPE 注释类型声明 
                ElementType.CONSTRUCTOR 构造方法声明 
                ElementType.FIELD 字段声明(包括枚举常量) 
                ElementType.LOCAL_VARIABLE局部变量声明 
                ElementType.METHOD 方法声明 
                ElementType.PACKAGE 包声明 
                ElementType.PARAMETER 参数声明 
                ElementType.TYPE 类、接口(包括注释类型)或枚举声明

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

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

        注解相当于一种标记,在程序中加了注解等于为程序打上了标记。标记可以加在包、类、字段、方法、方法的参数以及局部变量上。

2、注解的定义

        从 JDK1.5 开始,java增加了对元数据(MetaData) 的支持,也就是 Annotation (注解)

        调用一个被注解标记的类或类的成员时,需满足注解必须早于类或成员的存在,即注解必须先得定义好,才能被应用

        注解应用结构图:

3、注解的各种属性

        首先自定义注解:

        public @interface MetaAnnotation {
                String value();
        }

        @Target({ElementType.METHOD,ElementType.TYPE})
        @Retention(RetentionPolicy.RUNTIME)
        public @interface MyAnnotation{
                String name();  //不含默认值的一般类型属性
                String colour() default "red"; //带默认值的一般类型属性
                int[] arrayAttr() default {1,2,3};//带默认值的数组型属性
                Enumeration.TrafficLamp lamp() default Enumeration.TrafficLamp.GREEN;//带默认值的枚举型属性
                MetaAnnotation annotationAttr() default @MetaAnnotation("JAVASE");//带默认值的注解型属性
        }

        如果数组的属性中已定义有默认值,那么在应用注解时,可不不给注解赋值;如果注解的属性没有默认值,在使用该注解的时候一定要给对应的属性赋值。如果注解中只有一个属性,那么可以直接写上属性的属性值即可,不必写属性 =  xxxxx ” 

  (1) 数组型属性

        int[ ] arrayAttr( ) default {1,2,3};

        注:如果数组属性中只有一个元素,这时候对该属性值赋值时可以省略大括号,如:MyAnnotation(arrayAttr = 1) 

  (2) 枚举型属性

        Enumeration.TrafficLamp lamp();

        应用:@MyAnnotation(lamp = Enumeration.TrafficLamp.GREEN)

        注:注解的属性没有默认值,在使用该注解的时候一定要给对应的属性赋值。

  (3) 注解型属性

        MetaAnnotation annotationAttr() default @MetaAnnotation("JAVASE");

        @MyAnnotation

  (4) @MyAnnotation(name = "xxx",colour = "blue",arrayAttr = 1,annotationAttr = @MetaAnnotation("JAVAEE")) ,可以认为这句话是 MyAnnotation 注解的一个实例对象。同理,@MetaAnnotation("JAVASE"); 也可以当作一个实例对象。那么即是对象,就可以对对象进行操作调用其内部成员:

        MetaAnnotation meta = MyAnnotation.class.getAnnotation(MyAnnotation.class).annotationAttr();
        System.out.println(meta.value());  //value MetaAnnotation 中的属性,返回:JAVASE 

   (5) 能够作为注解属性的类型有:原是类型(8个基本类型),StringClass 以及任何援用与Class的类型,枚举,注解和前面所有类型的数组型。

        注意:枚举和注解都是特殊的 Java 类,不能用new 创建对象,创建枚举的实例就是在枚举中在其中增加元素,创建注解的对象,直接在注解名前加一个即可。

4、实现反射对注解的操作

import java.lang.reflect.Method;
import java.util.Date;

@MyAnnotation(name = "Fff",colour = "blue",arrayAttr = 1,
annotationAttr = @MetaAnnotation("JAVAEE"))
public class AnnotationTest {

	/**
	 * @param args
	 */
	@SuppressWarnings("deprecation")//消除在编译时提示过时的信息
	@MyAnnotation(name = "Lll")		
	public static void main(String[] args) throws Exception{

		Date.UTC(2013, 4, 6, 4, 36, 54);
		depercate();
		
		//通过反射方式来获取类注解信息。
		if (AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)) {
			MyAnnotation annotation = AnnotationTest.class.getAnnotation
					(MyAnnotation.class);
			System.out.println(	annotation.name());						//Fff
			System.out.println(	annotation.colour());					//blue
			System.out.println(	annotation.arrayAttr().length);			//1
			System.out.println(	annotation.lamp().nextLamp().name().getClass());//class java.lang.String
			System.out.println(	annotation.annotationAttr().value());	//JAVAEE
		}
		//获取主函数上的注释声明信息。
		Method mainMethod = AnnotationTest.class.getMethod("main", String[].class);
		MyAnnotation annotation = 
				(MyAnnotation)mainMethod.getAnnotation(MyAnnotation.class);
		System.out.println(annotation.name());		//Lll
	}
	
	@Override
	public String toString() {
		return "AnnotationTest [getClass()=" + getClass() + 
				", toString()=" + super.toString() + "]";
	}

	@Deprecated
	public static void depercate(){
		System.out.println("过时了!");
	}
}

        上面的示例中比较详细讲解了通过反射对数组的操作以及怎么获取静态方法上的注解声明信息,其他如在包、类、字段、非静态方法、方法的参数上的注解声明信息的获取操作是一样的,只是要通过不同的表示这些类型的对象来操作。对于类中所有的描述信息(成员、修饰符、注解、包、参数等)在Java 中都有对应的对象将其封装。先获取当前类字节码的,在用字节码来获取对应描述信息的对象,那么该对象就可以进行一些定义好的操作。

 

 

 

 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值