注解的使用以及注意事项
2010-08-02 15:52
846 查看
注解是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.注解里的字段必须初始化
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.注解里的字段必须初始化
相关文章推荐
- java 使用quartz 定时xml 配置 与注解 以及注意事项
- popwindow分析以及使用注意事项(二)
- switch case default 语句的的使用以及注意事项
- oracle中创建序列以及序列使用注意事项
- 构造器内书写异常以及使用的注意事项---Thinking in java
- 关于常见的变量修饰符: const, static, extern, register, auto 的详细解释,使用场合以及注意事项
- 如何不用oracle client直接使用plsql远程连接oracle数据库以及需要注意的事项
- Hive - 建表和加载数据指令小结 以及使用Load data指令的注意事项
- apache 的FTPClient使用以及注意事项
- Qt中如何使用样式表QPalette以及相关注意事项
- MySQL索引类型总结和使用技巧以及注意事项
- MySQL索引类型总结和使用技巧以及注意事项
- zeromq 在ubuntu 下的编译命令,以及使用时的注意事项
- iPhone SDK中多线程的使用方法以及注意事项
- C语言-Switch 和case 的使用注意事项以及穿透效果的使用
- inline 函数的使用以及注意事项
- MySQL索引类型总结和使用技巧以及注意事项(转) 4000
- SpringMVC中关于@Resource与@Autowired注解的区别和使用注意事项
- PDO防注入原理分析以及使用PDO的注意事项总结
- hdu 1075 map的使用 字符串截取的常用手段 以及string getline 使用起来的注意事项