注解

package cn.itcast.day2;

@ItcastAnnotation
public class AnnotationTest {

	/**
	 * @param args
	 */
	@SuppressWarnings("deprecation")//注解,过时的就可以用了  压缩警告 一个注解是一个类 
					//@SuppressWarnings("deprecation")用于告诉javac编译器该怎样
	//@ItcastAnnotation
	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		System.runFinalizersOnExit(true);//语言过时了
		if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class))//ItcastAnnotation注解是保存在class里面的
		{
			ItcastAnnotation annotation=(ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
			System.out.println(annotation);
		}
	}
	
	//如果把方法删去了,以前调用的会报错.新人不用,老的可以继续调用
	//@Deprecated,这就说明这个方法已经作废。那么别人在引用的时候就会提示方法已经过时。
	@Deprecated
	public static void sayHello(){
		System.out.println("hi,hiahia");
	}

}

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

(二)应用
1、让已经过时的语言可以用   压缩警告
例:AnnotationTest.java
package cn.itcast.day2;

public class AnnotationTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.runFinalizersOnExit(true);//语言过时了
	}

}

在dos命令中执行:javac -Xlint:deprecation AnnotationTest.java
       来检查是具体哪里有问题
 
结果:
C:\Workspace1\javaenhance\src\cn\itcast\day2>javac -Xlint:deprecation AnnotationTest.java
AnnotationTest.java:10: 警告:[deprecation] java.lang.System 中的 runFinalizersOnExit(boolean) 已过时
                System.runFinalizersOnExit(true);//语言过时了
                      ^
1 警告
 
 
加注解:
@SuppressWarnings("deprecation")用于告诉javac编译器该怎样
package cn.itcast.day2;

public class AnnotationTest {

	/**
	 * @param args
	 */
	@SuppressWarnings("deprecation")//注解,过时的就可以用了  压缩警告 一个注解是一个类
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.runFinalizersOnExit(true);//语言过时了
	}

}

 

2、写过的方法,现在已经不用,但之前调用还可以继续用  标记语言方法过时

@Deprecated,这就说明这个方法已经作废。那么别人在引用的时候就会提示方法已经过时。

例:

//如果把方法删去了,以前调用的会报错.新人不用,老的可以继续调用
	@Deprecated
	public static void sayHello(){
		System.out.println("hi,hiahia");


 

如果再调用的话:

AnnotationTest.sayHello();

 

3、覆盖  子类是覆盖父类的方法

@Override


假如我们想覆盖类的equals方法:

public boolean equals(Point pt){
}
但是实际上这个方法并不是重写的Object的equals,如何限定我们就是覆盖的Object的equals而不会出错呢?当我们在方法前面加上@Override注解的时候,编译时就会提示我们其实并没有覆盖!

总结:

注解就是一个标记,加了注解就相当于给程序打了一种标记。

标记可以加载包上,类上,方法上,成员变量,方法的参数,方法的局部变量上面。

但是实际上这个方法并不是重写的Object的equals,如何限定我们就是覆盖的Object的equals而不会出错呢?当我们在方法前面加上@Override注解的时候,编译时就会提示我们其实并没有覆盖!


总结:注解就是一个标记,加了注解就相当于给程序打了一种标记。
标记可以加载包上,类上,方法上,成员变量,方法的参数,方法的局部变量上面。

java.lang包,可看到JDK中提供的最基本的annotation

 

(二)如何应用

注解就相当于一个你的源程序中要调用的一个类,要在源程序中应用某个注解,得先准备好了这个注解类。就像你要调用某个类,得先有开发好这个类。

 

注解类:
@interface A{
}

应用了“注解类”的类
@A
Class B{
}

对应用了注解类的类进行反射操作的类。
Class C{
   B.class.isAnnotationPresent(A.class);
   A a=B.class.getAnnotion(A.class);
}

例子:

在java透视图下,新建选择Annotation

 

main方法必须放在类里面,但main方法不见得属于这个类的成员

根据发射测试的问题,引出 @Retention 元注解的讲解,其三种取值: RetetionPolicy.SOURCE RetetionPolicy.CLASS RetetionPolicy.RUNTIME ; 分别对应: java 源文件 -->class 文件 --> 内存中的字节码。

 

因为ItcastAnnotation注解是保存在class里面的,当调用到内存里时就没有了

所以在注解类ItcastAnnotation.java里面加了一个RUNTIME:一直保留到运行期间


注解类:
ItcastAnnotation.java

package cn.itcast.day2;

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

//元注解,元数据,元信息
@Retention(RetentionPolicy.RUNTIME)//RUNTIME一直保留到运行期间
public @interface ItcastAnnotation {

}


应用了“注解类”的类

main方法必须放在类里面,但main方法不见得属于这个类的成员
AnnotationTest.java

package cn.itcast.day2;

import javax.jws.soap.InitParam;

@ItcastAnnotation(annotationAttr=@MetaAnnotation("flx"),color="red",value="abc",arrayAttr={1,2,3})
public class AnnotationTest {

	/**
	 * @param args
	 */
	@SuppressWarnings("deprecation")//注解,过时的就可以用了  压缩警告 一个注解是一个类 
					//@SuppressWarnings("deprecation")用于告诉javac编译器该怎样
	@ItcastAnnotation("xyz")
	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		System.runFinalizersOnExit(true);//语言过时了
		/*
		使用了AnnotatedElement类的isAnnotationPresent()方法判断某个方法是否具有@ItcastAnnotation.class
		    AnnotationTest.class得到AnnotationTest的字节码
		    ItcastAnnotation.class:只要是类,要表示它是不是class还是用字节码来表示
		如果有
		    AnnotationTest.class.getAnnotation(ItcastAnnotation.class);得到ItcastAnnotation.class的注解
		          但是不知道哪一个具体类型的注解(ItcastAnnotation)进行类型转换
		
		
*/		if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class))//ItcastAnnotation注解是保存在class里面的
		{
			ItcastAnnotation annotation=(ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
			System.out.println(annotation.color());
			System.out.println(annotation.value());
			System.out.println(annotation.arrayAttr().length);
			System.out.println(annotation.lamp().nextLamp().name());
			System.out.println(annotation.annotationAttr().value());
		}
	}
	
	//如果把方法删去了,以前调用的会报错.新人不用,老的可以继续调用
	//@Deprecated,这就说明这个方法已经作废。那么别人在引用的时候就会提示方法已经过时。
	@Deprecated
	public static void sayHello(){
		System.out.println("hi,hiahia");
	}
}



注:

@Override注解的@Retention在哪个阶段

         @Override是给javac看的,编译完就没有价值了,也就是说在源代码阶段有用,处理成class就没意义了,保留在source阶段

@SuppressWarnings

       SuppressWarnings是给编译器看的,source,运行期间

@Deprecated这个注解的@Retention

        Deprecated是给编译器看的

        源程序调用这个类,编译器提示过时了




        @SuppressWarnings("deprecation")//注解,过时的就可以用了  压缩警告 一个注解是一个类 
				//@SuppressWarnings("deprecation")用于告诉javac编译器该怎样
	public static void main(String[] args) throws Exception{
		
		System.runFinalizersOnExit(true);//语言过时了
		
		if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class))//ItcastAnnotation注解是保存在class里面的
		{
			ItcastAnnotation annotation=(ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
			System.out.println(annotation.color());
			System.out.println(annotation.value());
			System.out.println(annotation.arrayAttr().length);
			System.out.println(annotation.lamp().nextLamp().name());
			System.out.println(annotation.annotationAttr().value());
		}
	}

 编译器在处理@SuppressWarnings时,在源程序找@SuppressWarnings,如果runFinalizersOnExit过时了,编译器在源程序看不到runFinalizersOnExit过时了,

编译器从System的字节码身上才看得到。

编译器怎么知道runFinalizersOnExit过时了,一定是把System加载到内存来,读System的二进制,检查二进制是否有runFinalizersOnExit方法。

编译器拿到的是System类的二进制编码,所以它保留的就是运行期间



@Retention(RetentionPolicy.RUNTIME)这个注解的意思就是:要让注解一直保留到运行时。

 Retention:

1.当在源程序加上一个注解,这个源程序接着要由javac程序编译,javac把源文件编译成class
在编译成class的时候会把源程序里面的一些注解给去掉
 2.javac编译成class文件时保留了注解,在用的时候要用类加载器把class调到内存里面,类加载器会对class进行一个处理
 处理完后才是二进制的字节码,类加载器把class文件调到内存中也有转换,转换后class文件里面的注解是否留下来,也有说法
 所以说一个注解周期有三个阶段


当javac把源文件编译成class的时候,需要做一些处理,而当jvm用类加载器把class里面的二进制数据加载进内存的时候,也要做一些处理,然后生成字节码Class。
因此,一个注解的生命周期有三个阶段:源文件->class文件->字节码。在设计注解的时候就需要指定


设计注解时可以加上@Retention这个说明,说明这个注解的生命周期在哪,元注解三个阶段:RetentionPolicy.SOURCE(元文件阶段),RetentionPolicy.CLASS(默认值),RetentionPolicy.RUNTIME(运行阶段)
 

注解存在的生命周期,用@Retention来指定,默认是保留在class阶段。


Override的Retention是保留在source阶段,SuppressWarnings也是给编译器看的,保留在source阶段,Deprecated是保留在运行时Runtime。

Retention的取值是一个enum,这个enum的名字叫做:RetentionPolicy,有三个常量和两个方法,CLASS,RUNTIME,SOURCE和static RetentionPolicy valueOf(String name)  ,static


@Override、@SuppressWarnings返回的都是source

@Deprecated保留到运行阶段,因为我加在你身上,你这个类以后被别人用,别人知道过时了,别人不是在检查源代码,而是检查二进制代码,扫描有什么方法

他的@Retention填的值是个枚举,名称是RetentionPolicy


 @Retention:保存在哪个生命周期
@Target:说明用在那个成分上

注解可以加载到类的那些成份上,枚举的名称是什么
@Target用于标明标记可以加在的成分上(包,类,枚举,注解,接口,字段,方法,构造方法、方法的参数上和局部变量上)
   Type


(三)为注解增加属性

一个注解相当于一个胸牌,如:胸前贴了胸牌,就是学生,否则就不是。如果还想区分是哪个班的学生,可以在增加一个属性进行区分。

注解很像接口,他的属性很像方法

default属性的默认值,value属性的特殊运用

package cn.itcast.day2;

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

import cn.itcast.day1.EnumTest;
@Retention(RetentionPolicy.RUNTIME)//让ItcastAnnotation注解一直保留到RUNTIME运行期间
@Target({ElementType.METHOD,ElementType.TYPE})//枚举   (ElementType.METHOD)在方法上有注释,加上{ElementType.TYPE}就可以在类上用了
					 //用.TYPE而不是CLASS:因为class有一个父类时type,Type比class更精准,1.5以后出来的
public @interface ItcastAnnotation {
	/*
	 * 方法color,返回值String,这个方法是抽象的也是public的,不用加指定缺醒值,
	 * blue,可以不用必须写
	 */
	String color() default "blue";//为注解添加属性,添加
default "blue",
 @ItcastAnnotation("xyz")才可以用
String value();int[] arrayAttr() default {3,4,5};//数组类型注解EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED;//枚举类型注解MetaAnnotation annotationAttr() default @MetaAnnotation("lhm");}

 
@ItcastAnnotation(annotationAttr=@MetaAnnotation("flx"),color="red",value="abc",arrayAttr={1,2,3})用的时候为他设置属性@ItcastAnnotation(color="red")          /**
	 * @param args
	 */
	@SuppressWarnings("deprecation")                                                                                                                          @ItcastAnnotation("xyz")//只有value属性要设的时候,不用谢value=,因为注解里有              
public class AnnotationTest {
                        ItcastAnnotation annotation=(ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
			/*
			 * color用的时候以属性的形式用,设值的时候以属性的形式设值,
			 * 取值的时候,以以方法调用的形式调用
			 */System.out.println(annotation.color());//结果是red                                                                                                       }


方法一:在方法上边注释

package cn.itcast.day2;


public class AnnotationTest {

	/**
	 * @param args
	 */
	@SuppressWarnings("deprecation")//注解,过时的就可以用了  压缩警告 一个注解是一个类 
									//@SuppressWarnings("deprecation")用于告诉javac编译器该怎样
	@ItcastAnnotation
 	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		System.runFinalizersOnExit(true);//语言过时了
		if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class))//ItcastAnnotation注解是保存在class里面的
		{
			ItcastAnnotation annotation=(ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
			System.out.println(annotation);
		}
	}
	
	//如果把方法删去了,以前调用的会报错.新人不用,老的可以继续调用
	//@Deprecated,这就说明这个方法已经作废。那么别人在引用的时候就会提示方法已经过时。
	@Deprecated
	public static void sayHello(){
		System.out.println("hi,hiahia");
	}

}

package cn.itcast.day2;

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

//元注解,元数据,元信息
@Retention(RetentionPolicy.RUNTIME)//RUNTIME一直保留到运行期间
@Target(ElementType.METHOD)//枚举 
public @interface ItcastAnnotation {

}

 

 

方法二:在类上注释

package cn.itcast.day2;

@ItcastAnnotation
public class AnnotationTest {

	/**
	 * @param args
	 */
	@SuppressWarnings("deprecation")//注解,过时的就可以用了  压缩警告 一个注解是一个类 
									//@SuppressWarnings("deprecation")用于告诉javac编译器该怎样
	//@ItcastAnnotation
	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		System.runFinalizersOnExit(true);//语言过时了
		if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class))//ItcastAnnotation注解是保存在class里面的
		{
			ItcastAnnotation annotation=(ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
			System.out.println(annotation);
		}
	}
	
	//如果把方法删去了,以前调用的会报错.新人不用,老的可以继续调用
	//@Deprecated,这就说明这个方法已经作废。那么别人在引用的时候就会提示方法已经过时。
	@Deprecated
	public static void sayHello(){
		System.out.println("hi,hiahia");
	}

}

package cn.itcast.day2;

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

//元注解,元数据,元信息
@Retention(RetentionPolicy.RUNTIME)//RUNTIME一直保留到运行期间
@Target({ElementType.METHOD,ElementType.TYPE})//枚举 Target里面用数组   加上{ElementType.TYPE}就可以在类上用了
public @interface ItcastAnnotation {

}


(四)为注解增加高级属性

 数组类型的属性

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

     @MyAnnotation(arrayAttr={2,3,4})

     如果数组属性中只有一个元素,这时属性值部分可以省略大括号

枚举类型的属性

     EnumTest.TrafficLamp lamp();

     @MyAnnotation(lamp=EnumTest.TrafficLamp.GREEN)

注解类型的属性


注解返回的类型能是:原始类型,String,Class,还可以是枚举类型,注解类型

     class

例如:

@ItcastAnnotation(a=String.class)  //a属性的返回值是class:String.class



注解类:

package cn.itcast.day2;

public @interface MetaAnnotation {
	String value();
}

package cn.itcast.day2;

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

import cn.itcast.day1.EnumTest;

/*
 * 在注解上加的注解
 * 元注解,元数据,元信息
 */
@Retention(RetentionPolicy.RUNTIME)//RUNTIME一直保留到运行期间
@Target({ElementType.METHOD,ElementType.TYPE})//枚举   加上{ElementType.TYPE}就可以在类上用了
public @interface ItcastAnnotation {
	String color() default "blue";//指定缺醒值,blue,可以不用必须写
	String value();
	int[] arrayAttr() default {3,4,5};//数组类型注解
       EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED;//枚举类型注解
       MetaAnnotation annotationAttr() default @MetaAnnotation("lhm");
}



package cn.itcast.day2;

import javax.jws.soap.InitParam;

@ItcastAnnotation(annotationAttr=@MetaAnnotation("flx"),color="red",value="abc",arrayAttr={1,2,3})
public class AnnotationTest {

	/**
	 * @param args
	 */
	@SuppressWarnings("deprecation")//注解,过时的就可以用了  压缩警告 一个注解是一个类 
									//@SuppressWarnings("deprecation")用于告诉javac编译器该怎样
	@ItcastAnnotation("xyz")
	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		System.runFinalizersOnExit(true);//语言过时了
		if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class))//ItcastAnnotation注解是保存在class里面的
		{
			ItcastAnnotation annotation=(ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
			System.out.println(annotation.color());
			System.out.println(annotation.value());
			System.out.println(annotation.arrayAttr().length);//数组类型
		     System.out.println(annotation.lamp().nextLamp().name());//枚举类型
		     System.out.println(annotation.annotationAttr().value());//注解annotation的属性annotationAttr返回值还是注解,而这                                                                             //个注解上还有属性
		}
	}
	
	//如果把方法删去了,以前调用的会报错.新人不用,老的可以继续调用
	//@Deprecated,这就说明这个方法已经作废。那么别人在引用的时候就会提示方法已经过时。
	@Deprecated
	public static void sayHello(){
		System.out.println("hi,hiahia");
	}

}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值