注解

1、注解概述


  注解的作用:注解用来替代配置文件的,以前要写一些配置文件,例如web.xml,包含<servlet>和<servlet-mapping>等内容使Tomcat读取,Servlet3.0中可以使用注解来代替配置文件然后Tomcat来读取注解。

  注意:注解是类,需要定义了才能使用。例如,有一个注解类为@WebServlet,我们就可以在Servlet中使用@WebServlet这个注解,它用来替代<servlet>配置。然后Tomcat会通过反射来读取注解中的信息。


2、Java注解


  Java中常见注解:

     @Overrid:作用在方法上的注解。当方法不是重写父类的方法时会报错;

     @Deprecated:作用在方法上。标记该方法为作废方法(已过时);

     @SuppressWarnings:作用在方法上,压制警告。


3、注解类


  (1)定义注解类


    定义注解类不能使用class、enum,也不能使用interface,而是使用@interface。

<span style="font-size:18px;">public @interface MyAnn{}</span>


  (2)使用注解类


    注解可以作用在:类(接口或枚举)、属性、方法、构造器、包、参数、局部变量

<span style="font-size:18px;">package annocation;

@MyAnn
public class MyClass {
	@MyAnn
	private int a;
	@MyAnn
	public MyClass() {}
	@MyAnn
	public void fun1() {}
	@MyAnn
	public void fun2(@MyAnn String s) {
		@MyAnn
		int n = 10;
	}
}</span>


4、注解的属性


  定义注解时可以给出属性:


<span style="font-size:18px;">public @interface MyAnn { //定义了两个属性
	String value();
	int value1();
}</span>


  其中value和value1就是属性,它是一个方法,但我们非要称之为属性,因为当做属性更好理解。


  当为注解指定属性后,那么在使用注解时就必须要给属性赋值了:

<span style="font-size:18px;">@MyAnn(value1=100,value="hello") //给属性赋值
public class MyClass {
}</span>


  注解的属性还可以有默认值,在使用注解时就可以不给带有默认值的属性赋值了。但没有给出默认值的属性还是要赋值的。

<span style="font-size:18px;">public @interface MyAnn { 
	String value() default "hello world"; //带有默认值的属性
	int value1();
}
@MyAnn(value1=100) //在使用注解时,没有给value赋值,因为它有默认值,可以不再次赋值。但value1没有默认值,所以必须赋值。
public class MyClass {
}</span>


  value是注解中一个特殊的属性,在使用注解时,如果只给名为value的属性赋值,那么可以不给出属性的名称直接给出值。

<span style="font-size:18px;">public @interface MyAnn {  
	String value() default "hello world";
	int value1() default 100;
}
@MyAnn() //可以,因为value和value1都有默认值
public class MyClass {
}
@MyAnn(value="hello")  //给value赋值
public class MyClass {
}
@MyAnn(value1=200) //给value1赋值
public class MyClass {
}
@MyAnn(value="hello",value1=200)  //给value和value1赋值
public class MyClass {
}
@MyAnn("hello annocation") //没有给出属性名称,所以是给value赋值
public class MyClass {
}
@MyAnn(300)   //报错,value属性是String类型值
public class MyClass {
}
@MyAnn("hello",value1=200) //报错,只有当注解类只有一个属性时,才能省略value=
public class MyClass {
}</span>


  需要注意问题:

     注解的属性后面要有一对圆括号,而且圆括号内不能给出东西。就像是无参的方法一样;

     注解的属性类型只能是:基本类型、String、Enum、Class、注解类型、以上类型的一维数组类型;

     注解的属性可以有默认值,例如:int a() default 100;

     数组的属性默认值:int[] arr() default {1,2,3},这里不能使用new int[]{1,2,3}

     使用注解时,在给数组属性赋值时的格式:@MyAnn(arr={1,2,3});


5、注解的作用目标


  在定义注解时可以限制注解的作用目标,例如让注解只能作用在类和方法上。

  这需要使用元注解:@Target。该注解有一个属性value,类型为ElementType[],它是枚举类型,其中定义了类(接口或枚举)、属性、方法、构造器、包、参数、局部变量等类型。


<span style="font-size:18px;">public @interface Target {
    ElementType[] value();
}
public enum ElementType {
  TYPE,FIELD,METHOD,PARAMETED,CONSTRUCTOR,LOCAL_VARIABLE,ANNOCATION_TYPE,PACKAGE
}</span>


  在定义注解时,可以使用@Target注解来限制注解的作用目标:

<span style="font-size:18px;">@Target({ElementType.TYPE, ElementType.METHOD})  //只能作用在类(接口)、方法上
public @interface MyAnn {
}</span>


  这样MyAnn就只能作用在类和方法上的!其中ElementType.TYPE表示类和接口。

<span style="font-size:18px;">@MyAnn()
public class MyClass {   //报错,因为只能作用在类和方法上
	@MyAnn()
	private int a;
	
	@MyAnn()
	public void fun() {}
}</span>


6、注解的保留策略


  注解的保留策略是指,把注解只保留在源代码上(编译时会失去);还是保留到class文件上,再或者是类在运行时,可以被类加载器加载到内存中。如果希望注解被反射,那么注解就要保留到运行时,而不是源代码或类文件上。

  指定注解的保留策略需要使用元注解@Retention,它有一个value属性,类型为RetentionPolicy类型,RetentionPolicy是枚举类型:


<span style="font-size:18px;">public @interface Retention {
    RetentionPolicy value();
}
public enum RetentionPolicy {
    SOURCE, CLASS, RUNTIME   //source表示源代码,后面分别表示Class文件、运行时
}</span>


  下面代码是指定注解保留到运行时:

<span style="font-size:18px;">@Retention(RetentionPolicy.RUNTIME)  //表示注解保留到运行时
@Target({ElementType.TYPE, ElementType.METHOD}) //注解可以作用在类(接口)、方法上
public @interface MyAnn {
	String value() default "hello";
	int value1() default 100;
}</span>


7、通过反射读取注解


  读取注解需要使用反射来完成:


    定义注解MyAnn:

<span style="font-size:18px;">@Retention(RetentionPolicy.RUNTIME)  //表示注解保留到运行时,如果不保留到运行时,不能使用反射
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyAnn {
	String value() default "hello";
	int value1() default 100;
}</span>


    将注解作用在类、方法上:

<span style="font-size:18px;">@MyAnn(value="hello world", value1=200)
public class MyClass {
	private int a;
	
	@MyAnn("myMethod") //给value属性赋值
	public void fun() {}
}</span>


    反射:

<span style="font-size:18px;">public class Demo1 {
	public static void main(String[] args) throws Exception {
		Class clazz = MyClass.class; //得到Class对象
		MyAnn myAnn = (MyAnn) clazz.getAnnotation(MyAnn.class); //获取注解
		System.out.println(myAnn.value());
		System.out.println(myAnn.value1());
		
		Method method = clazz.getMethod("fun"); //反射得到方法对象
		MyAnn myAnn1 = method.getAnnotation(MyAnn.class);
		System.out.println(myAnn1.value());
		System.out.println(myAnn1.value1());
	}
}</span>


  小结:Java中注释是给人看的,而注解是给程序看的。注解主要用来代替配置文件,但是注解相对于配置文件的缺点是,修改时必须修改代码,而且不能完全替代配置文件;优点是方便、简单。



  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值