黑马程序员-java学习笔记-注解

---------------------- android培训、java培训、期待与您交流! ----------------------

JDK 5中引入了源代码中的注解(annotation)这一机制。注解使得Java源代码中不但可以包含功能性的实现代码,还可以添加元数据。注解的功能类似于代码中的注释,所不同的是注解不是提供代码功能的说明,而是实现程序功能的重要组成部分。Java注解已经在很多框架中得到了广泛的使用,用来简化程序中的配置。

我们接触过最多的注解就@overwrite,这是用在子类覆盖父类的方法的时候出现的

黑马程序员-java学习笔记-注解_第1张图片

注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。


我们再来看看@SuppressWarnings()


加入@SuppressWarnings()后,在用javac编译时,不会警告说该方法以及过时了。(MyEclipse做得不够智能,没有去掉下划线)

一个注解就是一个类,用这个注解就相当于创建了这个类的实例对象。

自定义一个注解

eclipse中很方便的为我们创建注解,和创建类和接口一样

黑马程序员-java学习笔记-注解_第2张图片

得出以下代码

public @interface ItcastAnnotation{
}

注解就是在接口上加了一个@


接下来调用一下,这里我们运用了反射进行操作

public static void main(String[] args) throws Exception{
if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)){
			ItcastAnnotation annotation = (ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
}
对annotation进行打印输出,结果没有任何反应,说明if()语句为false,内部语句没有执行。
既然如此,我们对注解类进行修改,加入新的注解,称为元注解(注解中还有注解),类似的称呼还有元信息、元数据等

@Retention(RetentionPolicy.RUNTIME)
public @interface ItcastAnnotation {
}

结果成功打印输出


为什么加入了@Retention()之后,就可以打印出来了呢?
因为自定义注解的生命周期指保留在.class文件,当载入内存后,自定义注解就消失了。加入@Retention(RetentionPolicy.RUNTIME)后自定义注解的生命周期延长到了运行时,所以可以打印输出了。

元注解介绍

既然元注解在注解中很重要,有必要介绍常用的两个注解了。

@Retention元注解
该元注解可以取三种值:RetetionPolicy.SOURCE、RetetionPolicy.CLASS、RetetionPolicy.RUNTIME;

分别对应:java源文件、class文件、内存中的字节码。

@Targe元注解

@Target用来声明注解可以被添加在哪些类型的元素上,如类型、方法和域等。

小试一下@target

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItcastAnnotation {
}

1)有点看不明白了,为何@Target上可以{demo1,demo2}这种格式添加?
通过查看文档,因为ElementType是一个数组。

2)那ElementType又是什么呢?

程序元素类型。此枚举类型的常量提供了 Java 程序中声明的元素的简单分类。

这些常量与 @Target元注解类型一起使用,以指定在什么情况下使用注释类型是合法的。

3)为何声明注解可以在类上使用是用ElementType.TYPE,而不是CLASS?

Class类的父类为Type,这是jdk1.5增加的新类型,接口、类、枚举和注解都是java中的一种类型,用Type描述这类事物

元注解以及其枚举属性值不用记,只要会看jdk提供那几个基本注解的API帮助文档的定义或其源代码,按图索骥即可查到,或者直接看java.lang.annotation包下面的类。


为注解增加基本属性
一个注解相当于一个胸牌,如果你胸前贴了胸牌,就是传智播客的学生,否则,就不是。如果还想区分出是传智播客哪个班的学生,这时候可以为胸牌在增加一个属性来进行区分。加了属性的标记效果为:@MyAnnotation(color="red")
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItcastAnnotation {
	String color();
}

这里创建了一个String类型的属性 color();创建注解的同时,也要设置属性
@ItcastAnnotation(color="red")
public class AnonotationTest{
}
这和我们平时看到的注解有些许不一样,看看@SuppressWarnings
@SuppressWarnings("deprecation")
括号内的字符串也是属性,但是省略了名字,该名字非常的特殊
String value();
如果只有value()属性赋值,可以不写名字和等号了,就像@SuppressWarnings
但是如果除了value属性,还有其他属性,比如color,需要设置缺省值
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItcastAnnotation {
	String color() default "blue";
}

结合上面的知识,分析一下
@Retention(RetentionPolicy.RUNTIME)
分析:这个属性的返回值是RetentionPolicy,是一个枚举值, 属性的名字是value,所以可以省略名字和等号不写

刚才我们把color声明为String类型,那注解的属性可以声明为哪些类型呢?
注解的返回值是八种基本类型,String,Class,数组,枚举,注解本身。

数组类型的属性
int [] arrayAttr() default {1,2,3};
@MyAnnotation(arrayAttr={2,3,4})

如果数组属性中只有一个元素,这时候属性值部分可以省略大括
枚举类型的属性

EnumTest.TrafficLamp lamp() ;
@MyAnnotation(lamp=EnumTest.TrafficLamp.GREEN)

注解类型的属性:
MetaAnnotation annotationAttr() default @MetaAnnotation("xxxx");
@MyAnnotation(annotationAttr=@MetaAnnotation(“yyy”) )

可以认为上面这个@MyAnnotation是MyAnnotaion类的一个实例对象,同样的道理,可以认为上面这个@MetaAnnotation是MetaAnnotation类的一个实例对象,调用代码如下:
	MetaAnnotation ma =  myAnnotation.annotationAttr();
	System.out.println(ma.value());

注解的详细语法可以通过看java语言规范了解,即看java的language specification。



---------------------- android培训、java培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net


你可能感兴趣的:(黑马程序员-java学习笔记-注解)