------- android培训、java培训、期待与您交流! ----------
33.了解和入门注解的应用
1.java提供的几个基本注解
1)@SuppressWarnings压制警告注解
使提示不再出现。如:@SuppressWarnings("deprecation")//不再提示过时
2)@Deprecated使过时注解
标识某个方法或类等已过时,以告诉新人以后尽量不要再使用该方法,同时又
不会影响以前的老程序。
3)@Override覆盖注解
在了类覆盖父类方法时,将非法的覆盖标识出来(或使不正确的覆盖报错),以便修正。
2.过时的两种表现方式演示:
1)在eclipse中会直接用删除线标识出来。
2)命令行的演示:
<1>普通演示 F:\lx\heima\practice\javaenhance>javac AnnotationTest.java
注意:AnnotationTest.java 使用或覆盖了已过时的 API。
注意:要了解详细信息,请使用 -Xlint:deprecation 重新编译。
<2>显示具体位置 F:\lx\heima\practice\javaenhance>javac -Xlint:deprecation AnnotationTest.java
AnnotationTest.java:8: 警告:[deprecation] java.lang.System 中的 runFinalizersOn
Exit(boolean) 已过时
System.runFinalizersOnExit(true);
^
1 警告
3.注解的定义和作用
1)注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记。java编译器,开发工具,
和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应
的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。
2)一个注解就是一个类,使用一个注解就相当于创建了一个注解类的实例对象。
34.注解的定义与反射调用
1.注解的应用结构图
注解类
@interface A
{
}
应用了"注解类"的类
@A
class B
{
}
对"应用了注解类的类"进行反射操作的类
class C
{
B.class.isAnnotionPresent(A.class);
A a = B.class.getAnnotion(A.class);
}
2.eclipse使用技巧之创建注解
1)包上右键-->New -->other-->java-->Annotation
2)切换到java视图-->包上右键-->New-->Annotation-->输入名字:ItcastAnnotation-->finish
3.添加元注解的原因分析:
1)javac 将源文件编译成字节码文件的时候,会将一些不太重要(包括注解在内)的东西去掉。
2)也可能注解保留到class文件中,类加载器将class文件调到内存过程中也有转换,把class文件
里面的注解去掉,最终得到的才是字节码文件。(class文件中的东西不是字节码,处理以后才是)
4.注解的生命周期
java源文件--->class文件--->内存中的字节码
@Retention元注解可定义注解的存在阶段。其取值有三个:
RetetionPolicy.SOURCE,RetetionPolicy.CLASS,Retetionpolicy.RUNTIME(保留到运行期间)
几个基本注解对应的阶段:
SuppressWarnings --- SOURCE
Override --- SOURCE
Deprecated --- RUNTIME
注:
Annotation Type Deprecated
@Retention(value=RUNTIME)
RUNTIME的类型为:Enum RetentionPolicy的字段
5.JDK1.5以后出现的类型TYPE定义包括:
class,interface,@interface,Enum等
Type比class更加精准
Class的父类是interface Type(java.lang.reflect包)
6.枚举ElementType(java.lang.annotation )
1)程序元素类型。此枚举类型的常量提供了 Java 程序中声明的元素的简单分类。
这些常量与 Target 元注释类型一起使用,以指定在什么情况下使用注释类型是合法的
2)枚举常量摘要
ANNOTATION_TYPE
注释类型声明
CONSTRUCTOR
构造方法声明
FIELD
字段声明(包括枚举常量)
LOCAL_VARIABLE
局部变量声明
METHOD
方法声明
PACKAGE
包声明
PARAMETER
参数声明
TYPE
类、接口(包括注释类型)或枚举声明
7.元注解Target()指定注解应用的位置
@Target(ElementType.METHOD):应用在方法上
@Target({ElementType.METHOD,ElementType.TYPE}):应用在方法和类上
8.代码演示:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItcastAnnotation
{
}
详见ItcastAnnotation.java和AnnotationTest.java
35.为注解增加各种属性
1.什么是注解的属性
一个注解相当于一个胸牌,如果你胸前贴了胸牌,就是传智播客的学生,否则,就不是。
如果还想区分出是传智播客哪个班的学生,这时候可以为胸牌再增加一个属性来进行区分。
加了属性的标记效果为:@MyAnnotation(color="red")
2.定义属性的几种方式
1)定义基本属性和应用属性
String color();---->@MyAnnotation(color="red");
2)数组类型的属性
int[] arrayAttr() default {1,5,2};--->@MyAnnotation(arrayAttr={5,8,9});
若数组属性中只有一个元素,属性值部分可以省略大括号
3)枚举类型的属性
EnumTest.TrafficLamp lamp();--->@MyAnnotation(lamp=EnumTest.TrafficLamp.GREEN);
4)注解类型的属性:
MetaAnnotation annotationAttr() default @MetaAnnotation("xxxx");--->
@MyAnnotation(annotationAttr=@MetaAnnotation("yyy"));
可以认为@MyAnnotation是MyAnnotation类的一个实例对象,@MetaAnnotation是MetaAnnotation类的一个实
例对象,调用代码为:
MetaAnnotation ma = myAnnotation.annotationAttr();
System.out.priintln(ma.value());
3.为属性指定缺省值:
String color() default "yellow";//就是在不赋值情况下默认的值
4.value属性:
String value() default "zxx";
如果注解中有一个名称为value的属性,且你只想设置value属性(即其他属性都采用默认值或者你
只有一个value属性),那么可以省略value=部分,如:@MyAnnotation("1hm");
5.用反射方式获得注解对应的实例对象后,再通过该对象调用属性对应的方法
MyAnnotation a = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
System.out.println(a.color());
可以认为上面这个@MyAnnotation是MyAnnotation类的一个实例对象
6.注:
枚举和注解都是特殊的类,不能用new创建它们的实例对象,创建枚举的实例对象就是在其中增加元素。
在程序中创建注解的实例对象,就是直接用@放上一个标记即可。
@ItcastAnnotation(class1=String.class,annotationAttr=@NetaAnnotation("flx"),color="red",value="abc",arrayAttr={1,2,3})
//如果只有value属性可以 @ItcastAnnotation("abc")
//或者别的属性 设置 default"" 设置默认值
public class AnnotationTest33 {
//设置注解的属性时像变量一样赋值,分别设置String、int[]、注解、枚举类型的属性的值
@SuppressWarnings("deprecation")// Suppress抑制Warnings警告 deprecation 弃用 RetetionPolicy.CLASS
public static void main(String[] args) {
sayHello();
/* @Override RetetionPolicy.SOURCE
表示一个方法声明打算重写超类中的另一个方法声明。
如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。*/
if(AnnotationTest33.class.isAnnotationPresent(ItcastAnnotation.class)){
ItcastAnnotation annotation=(ItcastAnnotation)AnnotationTest33.class.getAnnotation(ItcastAnnotation.class);
System.out.println(annotation.color());
System.out.println(annotation.value());
System.out.println(Arrays.toString(annotation.arrayAttr()));
System.out.println(annotation.enum1());
System.out.println(annotation.annotationAttr().value());
System.out.println(annotation.class1());
}
}
@Deprecated//过时弃用 RetetionPolicy.RUNTIME
public static void sayHello() {
System.out.println("Test");
}
}
/*
* 元注解
*/
@Retention(RetentionPolicy.RUNTIME)//生命周期
@Target ({ElementType.METHOD,ElementType.TYPE})//元素类型
public @interface ItcastAnnotation {
String color() default "默认值";
String value();
int[]arrayAttr();
EnumAnnotation enum1() default EnumAnnotation.one;
NetaAnnotation annotationAttr() default @NetaAnnotation ("lnm");
Class class1() default Integer.class ;
//可以认为@NetaAnnotation是NetaAnnotation的实例对象
}