注解的使用以及注意事项

来源:互联网 发布:网络研修总结作业 编辑:程序博客网 时间:2024/05/18 00:01

注解是JDK1.5以后出现的一个新特性,注解的出现使代码变得更加灵活,更为重要的是,程序员可以通过注解控制程序运行时的行为和状态,下面通过自定义的类,方法以及字段三种注解例子说一下注解的用法以及注意事项, 注意事项在注释里,使用代码时需要导入junit4的jar包

 



package com.annotation;

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

//注解类型的注解要保留多久,也称时效范围,此处要通过反射去读取注解,将Retention的值选为Runtime,
//也可以选择CLASS,SOURCE,CLASS表示编译器将把注解记录在类文件中,但在运行时 VM 不需要保留注解,
//即在源码中有效,这是默认的行为,SOURCE表示编译器要丢弃的注解。
@Retention(RetentionPolicy.RUNTIME)
//指示注解类型所适用的程序元素的种类,TYPE是指类、接口(包括注解类型)或枚举声明
//METHOD表示方法声明,FIELD表示字段声明(包括枚举常量)
@Target(ElementType.TYPE)
public @interface MyAnnotationClass {
 public String msgClass();
}

 

 

package com.annotation;

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)
public @interface MyAnnotationMethod {
 
 public String msgMethod();

 public String msgMethodPro();

 //注解只能用public 或abstract
 abstract int begin();
 //注解里的字段必须初始化
 public int testCount =1;
}


package com.annotation;

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.FIELD)
public @interface MyAnnotationField {
 public String msgField();

 public String msgFieldPro();

 public boolean open();
}

package com.annotation;

@MyAnnotationClass(msgClass = "类注解")
public class MyAnnotationDemo {
 @MyAnnotationField(msgField = "注解1", msgFieldPro = "字段1", open = false)
 public String testField;
 
 private static MyAnnotationDemo myAnnotationDemo;

 private MyAnnotationDemo() {
  testField = "RED FLAG RPG";
 }

 public synchronized static MyAnnotationDemo getInstance() {
  if (myAnnotationDemo == null) {
   myAnnotationDemo = new MyAnnotationDemo();
  }
  return myAnnotationDemo;
 }

 @MyAnnotationMethod(msgMethod = "注解2", msgMethodPro = "方法2", begin = 1)
 public void testRPG() {
  System.out.println(testField);
 } 
}

package com.annotation;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class MyAnnotationDemoTest {
 /**
  * @throws java.lang.Exception
  */
 @Before
 public void setUp() throws Exception {
 }

 /**
  * @throws java.lang.Exception
  */
 @After
 public void tearDown() throws Exception {
 }

 /**
  * Test method for {@link MyAnnotationDemo#testRPG()}.
  */
 @Test
 public final void testTestRPG() {
  // 获取实例
  MyAnnotationDemo myAnnotationDemo = com.annotation.MyAnnotationDemo
    .getInstance();
  // myAnnotationDemo.testRPG();
  // 使用反射获取注解信息
  MyAnnotationClass myAnnotationClass = myAnnotationDemo.getClass()
    .getAnnotation(MyAnnotationClass.class);
  // 类注解
  System.out.println("类注解msgClass:" + myAnnotationClass.msgClass());
  try {

   // 反射获得的字段必须是公共成员字段
   Field field = myAnnotationDemo.getClass().getField("testField");
   MyAnnotationField myAnnotationField = field
     .getAnnotation(MyAnnotationField.class);
   // 字段注解
   System.out.println("字段注解msgField:" + myAnnotationField.msgField()
     + ",msgFieldPro:" + myAnnotationField.msgFieldPro()
     + ",open:" + myAnnotationField.open());
   /*
    * Method[] methods = myAnnotationDemo.getClass().getMethods(); for
    * (Method methodTmp : methods) {
    * System.out.println(methodTmp.getName()); }
    */
   // 用反射获取方法,getMethod("testRPG",new Class[0])中"testRPG"表示方法名,
   // new Class[0]表示方法的参数个数为0个,如果new Class[2]就表示参数个数为2个,
   // 如果有多个参数个数相同但类型不同的方法,则任选一个(详见JDK1.6)
   Method method = myAnnotationDemo.getClass().getMethod("testRPG",
     new Class[0]);
   MyAnnotationMethod myAnnotationMethod = method
     .getAnnotation(MyAnnotationMethod.class);
   // 方法注解
   System.out.println("方法注解msgMethod:"
     + myAnnotationMethod.msgMethod() + ",msgMethodPro:"
     + myAnnotationMethod.msgMethodPro() + ",begin:"
     + myAnnotationMethod.begin() + ",testCount:"
     + myAnnotationMethod.testCount);

  } catch (SecurityException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchFieldException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }
}

 

 * 综合上面的例子,在开发自定义注解时,需要注意以下几点:
 * 1.注解的实效范围
 * 2.注解适用的程序元素种类
 * 3.注解里的方法和字段只能用public 或abstract
 * 4.注解里的字段必须初始化