JavaSE基础—Annotation(注解)

一、OverView

        注解在JavaSE中属于一种高级的用法,在项目以及很多的框架结构中都使用到了注解这种特殊用法,注解是在JDK1.5之后的一个新特性。在我们开始编写Java代码的时候,经常会在代码中生成@Override(重写) @Deprecated(f废弃的) @SuppressWarnings(压缩警告),这是在JDK1.5之后提供的常用注解。
        
        首先来一段小的Code,预热一下。

      public class Demo{

	public static void main(String[] args) {
	     funDeprecated();
	}

	@Deprecated
	public static void funDeprecated(){
	    System.out.println("这是一个过期的方法");
	}

	public Thread createThread() {
	  return new Thread(new Runnable() {
	  @Override
	   public void run() {
	      System.out.println("这是一个重写的方法");
	   }
	 });
	}


	@SuppressWarnings({ "unused", "resource" })
	public void readFile(String path) throws FileNotFoundException{
	  File f = new File(path);//unused一个
	   InputStream stream = new FileInputStream(path);//unused resource两个
	 }
     }
	


       
       在很多博客及书籍的地方有的将Annotation称为“注释”,其实是不对的,注释和注解是两个完全不同的概念,注解具有非常浓重的“Code”色彩,这个特性是注释完全不能表达的。注释给编程、测试人员看的,而注解有一部分是面向程序员的,但是更多的是面向于编译器的。注解简单的讲就是一种标记方式,在程序的特定的方式打上标记,这样编译器等工具就可以在相应的位置进行处理。注解可以标记在package , class , field , method , parameter , local variable之上。

二、Meta Annotation

        元注解(Meta Annotation)是注解的注解,就是在定义注解的时候使用的注解,用来控制自定义注解的最作用对象,生命周期等特性。

       2.1 @Retention

        Java在编译的过程中主要经理了3个阶段:
        (1) 编程人员编写得到java源代码(.java)                        -------------------------》RetentionPolicy.SOURCE
        (2) 使用javac将java源代码编译成为.class文件             -------------------------》RetentionPolicy.CLASS
        (3) JVM将class文件解释成为字节码文件(0,1组合的二进制)  -----------------》RetentionPolicy.RUNTIME

        RetentionPolicy.RUNTIME可以让你从JVM中读取Annotation注解的相关信息,以便在程序分析的时候使用。

        上述的三个值对应了java程序对应的三个阶段,当为自定义注解添加了对应的生命周期后,一旦对应的java阶段完成之后就会将该注解去掉。例如:加入一个注解添加了@Retention(RetentionPolicy.RUNTIME) 这样的注解,那么在编译成class文件之后该注解就去掉了。
        在JAVA中常见的三种注解 @Override @SuppressWarnings的生命周期是SOURCE , @Deprecated的生命周期是RUNTIME

       2.2 @Target

         Target可以控制自定义注解的作用对象,如field method等。使用方法为:
         @Target(ElementType.FIELD)
         
         Tips:如果注解中有value属性而且你在使用它,那么可以省略value =****,直接写属性值,就像上面@Target一样,也就是上述注解的完整写法是:
          @Target(value = ElementType.FIELD)

三、Instruction

       3.1 注解的定义

          注解的定义格式和类十分相似,也有对应的属性,具体的语法格式为:
          
           元注解
           public @interface  注解名{
                   属性定义[默认值]
           }       


          eg:

          @Retention(Retentionpolicy.SOURCE) 
          @Target({ElementType.METHOD,ElementType.Field})
          public @interface DemoAnnotation{
                 String classPath();     //注意属性定义的时候有一个括号
                 int endIndex() default 10; //为属性添加一个默认值
          }

       3.2 注解的使用和获取

        注解的使用和元注解一样,注解的获取通过相应类的class对象的getAnnotation方法获得。
        
@DemoAnnotation(classPath="com.test.mycode.impl.UserAction")
       public class Demo{
    
       public static void main(String[] args)
       {
        DemoAnnotation annotation = ( DemoAnnotation)Demo.getClass().getAnnotation(DemoAnnotation.class);
        System.out.println(annotation.classPath);
        System.out.println(annotation.endIndex);

}

}
       

       3.3 注解属性的一些扩展

        注解的属性除了常规的int float String等类型外,我们还可以定义一些其他类型,如数组、枚举类型等。
        数组:
            String[] name()   default {"AAA","BBB","CCC"}   使用的时候  @DemoAnnotation(name ={"aaa","bbb","ccc"})
            SexType sex()    default SexType.Male     其中SexType是一个枚举类型


四、Demo

       下面是一些综合练习
package com.test.mycode.main;

/**
 * 描述任务的优先级
 *
 */
public enum PriorityStatus {
	
	HIGH,
	MEDIUM,
	LOW	
}

package com.test.mycode.main;

/**
 * 
 * 设置一个元注解
 *
 */
public @interface MetaAnnotation {

	String value();
}

package com.test.mycode.main;

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 TaskAnnotation {

	String classPath();
	String value();
    int[] arrayCode() default {1,2,3};
    PriorityStatus status() default PriorityStatus.HIGH;
    MetaAnnotation annotation() default @MetaAnnotation("mytask");
}

package com.test.mycode.main;


@TaskAnnotation(
		
		classPath="com.test.mycode.MyTest",
		value = "MyTest",
	    arrayCode = {4,2,8},
	    status = PriorityStatus.HIGH,
	    annotation = @MetaAnnotation("mytask")
		)
public class MyTest {

	public static void main(String[] args) {
		
		if(MyTest.class.isAnnotationPresent(TaskAnnotation.class)) {//判断是否有该类型的注解
			
			//得到注解
			TaskAnnotation taskAnnotation = (TaskAnnotation)MyTest.class.getAnnotation(TaskAnnotation.class);
			
			System.out.println(taskAnnotation.classPath());
			System.out.println(taskAnnotation.value());
			System.out.println(taskAnnotation.arrayCode());
			System.out.println(taskAnnotation.status());
			System.out.println(taskAnnotation.annotation().value());
		}
		
	}
}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值