Java注解的使用
来源:互联网 发布:浏览器打开淘宝很卡 编辑:程序博客网 时间:2024/05/29 13:53
简介:注解就是程序的标注,利用反射解析到这些标注可以明确应用需要做什么事情
注解的语法比较简单,除了@符号的使用之外,它基本与Java固有语法一致。Java SE5内置了三种标准注解:
@Override,重写的注解,只能在方法上使用。 @Deprecated,用于声明不建议使用的方法,可以作用在类和方法上。 @SuppressWarnings,用于压制编译器警告。
上面这三个注解我们在进行方法重写,使用过时方法,定义集合没有给定具体泛型类型时会遇到,
除此之外Java还提供了4个注解,用于自定义注解,如下:
@Target
定义注解的使用位置
ElementType参数有:
CONSTRUCTOR:只能用在构造方法上
FIELD:只能用在字段和枚举常量上
LOCAL_VARIABLE:只能用在局部变量上
METHOD:只能用在方法上
PACKAGE:只能用在包上
PARAMETER:只能用在参数上
TYPE:只能用在类、接口、枚举类型上
@Retention
定义注解的保存范围。
RetentionPolicy参数包括:
SOURCE:只会保留在.java源文件中,不会保留在编译好的.class文件中
CLASS:会保留在.java和.class文件中,但不会被加载到JVM机,
如果声明Retention没有指定RetencationPolicy取值范围,默认是CLASS
RUNTIME:会保留在.java和.class文件中,执行时也会被加载到JVM中,常用的一种方式,因为通过反射可以获取到。
@Document
用于生成doc文档
@Inherited
标注该注解是否可以被继承,如果没有标注默认是不能被继承
public @interface MyAnnotation { //正确定义变量的方式 public String value(); //错误定义变量的方式,编译会提示Annotation attributes cannot have parameters public String value1(String value); //错误定义变量的方式,编译会提示Syntax error on token "throws", default expected public String value2()throws Exception; }
使用自定义注解:
//使用自定义注解并给value设置内容@MyAnnotation(value = "HG") public class TestMyAnnotation {}
在注解中设置多个变量
public @interface RequestMapping { public String value(); public String method();}
为注解中多个变量设置内容
@RequestMapping(value="login",method="GET") public class TestRequestMappin {}
在注解中定义数组变量
public @interface MyAnnotationArray { public String[] value();}
为注解中的数组设置内容
@MyAnnotationArray(value={"我是一个吃货","好巧啊我也是,要不你请我辣条呗"})public class TestMyAnnotationArray {}
默认值:在进行自定义注解时,如果注解中定义了变量,但是在实际使用中没有为其赋值,编译器就会出现错误,如下
@RequestMapping public class TestRequestMappin {}
以上在编译时就会出现The annotation @RequestMapping must define the attribute value,也就是说只要在定义
注解时声明了变量,那么在使用时必须为其赋值,所以有时候为了方便使用,也可以在定义注解变量时就指定默认值
public @interface RequestMapping { public String value() default "login.do"; //设置默认值 public String method() default "GET"; //设置默认值}
以上是为了在使用注解时,如果没有设置内容,就会将默认值赋给变量,如果明确给出了内容就会覆盖默认值。
使用枚举限制设置的内容
使用枚举限制设置的内容public enum MyEnum{ //定义枚举 DRAGON,WARDRAGON,HG;}public @interface MyAnnotationEnum { /** * 变量的返回类型是一个枚举,那么在为这个变量设置内容的 * 时候只能设置枚举中的内容 */ public MyEnum enums() default MyEnum.DRAGON; }
使用MyAnnotation
//错误的设置内容,会提示Type mismatch: cannot convert from String to MyEnum@MyAnnotationEnum(enums="呵呵") //正确的设置内容@MyAnnotationEnum(enums=MyEnum.DRAGON) public class TestMyAnnotationEnum {}
Retention:Retention中定义了一个RetentionPolicy主要是来指定注解的保存范围
使用Retention
/** * 该注解在.class中有效,也就是存在于JVM中,可以通过反射的getAnnotations()获取 */@Retention(value=RetentionPolicy.RUNTIME) public @interface myRetention { public String name() default "我喜欢吃猪耳朵!";}
利用反射获取到注解:使用JDK1.5提供的@Override、@Deprecated、@SuppressWarnings
public class ReflectAnnotationDemo { @Override //SOURCE @Deprecated //RUNTIME @SuppressWarnings("unchecked") //SOURCE public String toString() { return "我是一个吃货"; }}
获取方法上声明的所有注解
public class ReflectDemo01 { /** * 反射:运行时动态获取类内部的信息 * * 注解的声明有三种,分别是:SOURCE、CLASS、RUNTIME只有RUNTIME是存在于JVM中的 * 所以利用反射只能拿到RUNTIME声明的注解 */ public static void main(String[] args)throws Exception{ Class<?> c = Class.forName("com.dragon.Ann.ReflectAnnotationDemo"); Method toM = c.getMethod("toString"); Annotation[] ann = toM.getAnnotations(); for(Annotation a : ann){ System.out.println(a); } }}
以上就通过反射取到了java.lang.Deprecated,是因为只有该类的使用了RetentionPolicy.RUNTIME进行声明,所以只有他可以取到
利用反射获取自定义注解的内容
//定义存在于JVM中的注解@Retention(RetentionPolicy.RUNTIME)public @interface RequestMapping { public String value(); public String method(); }
//使用RequestMapping注解public class TestRequestMappin { @RequestMapping(value="login",method="GET") public String test(){ return "我是一顿八碗饭的帅哥!"; }}
//获取指定的注解public class ReflectDemo02 { public static void main(String[] args) throws Exception { Class cl = Class.forName("com.dragon.Ann.TestRequestMapping"); Method toM = cl.getMethod("test"); if (toM.isAnnotationPresent(RequestMapping.class)) {//判断注解是否存在 // 取得指定注解 RequestMapping ann = toM.getAnnotation(RequestMapping.class); System.out.println("value="+ann.value()); System.out.println("method="+ann.method()); } }}
以上三个程序是从定义注解、使用注解、通过反射获取方法上声明的注解,其实只要适当的利用好反射,就可以将指定的内容设置到对应的操作中,这些操作在Spring中经常用到
Target:Target中定义了一个ElementType枚举变量,主要指定注解的使用位置
定义注解
@Target({ElementType.TYPE}) //可以在类、接口、枚举上使用public @interface MyTargetAnnotation { public String key() default "吃饭了吗"; public String value() default "吃了八碗";}
使用注解
@MyTargetAnnotation //在类上使用,无编译错误public class TargetDemo{ @MyTargetAnnotation //在方法上使用,编译错误 public String toString(){ return "我喜欢吃猪耳朵"; } }
如果希望定义的注解在类和方法上都可以使用,可以将注解声明为@Target({ElementType.TYPE,ElementType.METHOD}),括号中有{}括起来,表示在类和方法上都可以使用
Documented:用于生成DOC文档
定义注解
@Documentedpublic @interface MyDocumentedAnnotation { public String key(); public String value();}
使用注解
@MyDocumentedAnnotation(key = "HG", value = "胡歌")public class DocumentedDemo { /** * 你好啊 大胡哥 */ @MyDocumentedAnnotation(key = "HG", value = "胡歌") public String getHG() { return "你好 胡歌"; }}要生成doc文档需要进入命令行中执行:javadoc -d doc DocumentedDemo,然后就会在其目录下产生一个doc文件 Inherited:标注该注解是否可以被继承,默认是不能被继承 定义注解
@Retention(value=RetentionPolicy.RUNTIME)
public @interface MyInheritedAnnotation {
public String name();
}
使用注解
@MyInheritedAnnotation(name=”HG”)
public class Person {
}
public class InheritedReflectDemo { public static void main(String[] args)throws Exception{ Class<?> c = Class.forName("com.dragon.inherited.Student"); Annotation[] ann = c.getAnnotations(); for(Annotation a : ann){ //打印所有注解,如果注解上没有声明@Inherited则获取不到,默认是没有继承的 System.out.println(a); }}}
上面这个例子是通过反射验证是否被继承
- java注解的使用
- Java 注解的使用
- java 注解的使用
- Java注解的使用
- java注解的使用
- Java注解的使用
- java注解的使用
- java注解的使用
- java 注解的使用
- Java注解的使用
- Java注解的使用
- java 注解的使用
- JAVA注解的使用
- java注解的使用
- java注解的使用
- Java自定义注解及注解的使用
- java注解的编写,使用
- java --自定义注解的使用
- js正则表达式验证大全
- <转>全面分析 Spring 的编程式事务管理及声明式事务管理
- java反射笔记1
- 通配符选择器 列表修饰符 列表范围
- debug--T
- Java注解的使用
- linux的基本常识
- paint.ascent()和paint.descent()各自指的是什么意思呢
- 目录不是空的 无法删除
- 电池的电量与消耗问题
- 临界区
- Web浏览器性能测试及其调优
- 动态规划 最大子矩阵
- Java-出现The source attachment does not contain the source for the file xxx class