------- android培训、java培训、期待与您交流! ----------
黑马学习日志之二十三 Java高新技术(五)
1 注解
注解:Annotation 注解是JDK1.5 的新特性
简介:java.lang.SuppressWarnings是J2SE 5.0中标准的Annotation之一。 可以标注在类、字段、方法、参数、构造方法,以及局部变量上。
作用:向编译器传达信息,告诉编译器忽略指定的警告,不用在编译完成后出现警告信息。
使用:
@SuppressWarnings(“”)
@SuppressWarnings({})
@SuppressWarnings(value={})
例子:
@SuppressWarnings("unchecked")告诉编译器忽略 unchecked 警告信息。
@SuppressWarnings("serial"),警告信息:The serializable class WmailCalendar does not declare a static final serialVersionUID field of type long,使用这个注释将警告信息去掉。
@SuppressWarnings("deprecation")如果使用了使用@Deprecated注释的方法,编译器将出现警告信息。使用这个注释将警告信息去掉。
@SuppressWarnings("unchecked", "deprecation")告诉编译器同时忽略unchecked和deprecation的警告信息。
@SuppressWarnings(value={"unchecked", "deprecation"})
等同于@SuppressWarnings("unchecked", "deprecation")
@Deprecated:说明过时,方法不再使用,但是又不能删除,就使用该注解,提示过时
@Override: 方法覆盖
总结:
注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。
java.lang包,可看到JDK中提供的最基本的annotation。
2 注解的定义与反射调用
定义一个简单的注解:public @interface MyAnnotation {}把它加在某个类上:@MyAnnotation public class AnnotationDemot{}用反射进行测试AnnotationTest的定义上是否有@MyAnnotation
引出@Retention元注解:
@Retention(RetentionPolicy.RUNTIME):一直将注解保留到运行期间。
注解的生命周期,分为三个阶段,默认的阶段是Class文件阶段。
@Retention元注解的讲解,其三种取值:RetetionPolicy.SOURCE、RetetionPolicy.CLASS、RetetionPolicy.RUNTIME;分别对应:java源文件、class文件、内存中的字节码。
@Target元注解
Target的默认值为任何元素,设置Target等于ElementType.METHOD,原来加在类上的注解就报错了,改为用数组方式设置{ElementType.METHOD,ElementType.TYPE}就可以了。
元注解以及其枚举属性值不用记,只要会看jdk提供那几个基本注解的API帮助文档的定义或其源代码,按图索骥即可查到,或者直接看java.lang.annotation包下面的类
注解应用结构图
(1)注解类 @interface A{}
(2)应用注解的类
@A
class B
{
}
(3)对应用了注解类的类,进行反射操作的类
class c
{
B.class.isAnnotationPresent(A.class);
A a = B.class.getAnnotation(A.class);
}
一个源文件到运行状态的分析
源文件--〉class文件---〉内存中的字节码
(1)源文件经过 javac编译成class文件,
注释可以在这个阶段存在或去掉(RetetionPolicy.SOURCE)
(2)class文件(不是字节码)经过 类加载器加载到内存中变成字节码文件
注释可以在这个阶段存在或去掉(RetetionPolicy.CLASS)这个是注解的默认值默认阶段
(3)内存中字节码文件经过,java执行解释出来,变成程序。
注释可以在这个阶段存在或去掉(RetetionPolicy.RUNTIME)
例子:
package sun.itcast;
@ItcastAnnotation//此处可以加多个注释
public class AnnotationTest {
@SuppressWarnings("deprecation")//阻止警告信息
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
System.runFinalizersOnExit(true);
AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class);
ItcastAnnotation annotation =(ItcastAnnotation)AnnotationTest.class.
getAnnotation(ItcastAnnotation.class);
System.out.println(annotation);//控制台此句不能打印 说明if结果是false
}
@Deprecated//过时
public static void Hello(){
System.out.println("hello");
}
}
package sun.itcast;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//元注解 就是对注解再注解 元信息 信息的信息 元数据 数据的数据
@Retention(RetentionPolicy.RUNTIME)
//指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,
//则保留策略默认为 RetentionPolicy.CLASS。
//@Target(ElementType.METHOD)//注解只能用在方法上
@Target({ElementType.METHOD,ElementType.TYPE})//表示注解可以用在方法上 类上 接口上 枚举上等
//指示注释类型所适用的程序元素的种类。
//如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。
//如果存在这样的元注释,则编译器强制实施指定的使用限制。 例如,此元注释指示该声明类型是其自身,即元注释类型。
public @interface ItcastAnnotation {
}
3 为注解增加各种属性
为注解增加基本属性
注解的属性:一个注解相当于一个胸牌,如果你胸前贴了胸牌,就是传智播客的学生,否则,就不是。如果还想区分出是传智播客哪个班的学生,这时候可以为胸牌在增加一个属性来进行区分。加了属性的标记效果为:@MyAnnotation(color="red")
定义基本类型的属性和应用属性:
在注解类中增加String color();@MyAnnotation(color="red")
用反射方式获得注解对应的实例对象后,再通过该对象调用属性对应的方法
MyAnnotation a = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
System.out.println(a.color());
可以认为上面这个@MyAnnotation是MyAnnotaion类的一个实例对象
为属性指定缺省值:
String color() default "yellow";
value属性:
String value() default "zxx";
如果注解中有一个名称为value的属性,且你只想设置value属性(即其他属性都采用默认值或者你只有一个value属性),
那么可以省略value=部分,例如:@MyAnnotation("lhm")。
为注解增加高级属性
数组类型的属性
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。