之前写过自定义注解的例子,现在看一看,觉得有些东西还没有理解透彻,所以打算再重新整理一些会用得到的知识。
感谢下面这些博客的的分享:
http://blog.csdn.net/yixiaogang109/article/details/7328466
java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作
用。包含在 java.lang.annotation 包中。
1.元注解
元注解是指注解的注解。包括 @Retention @Target @Documented @Inherited四种。
1.1 @Retention
定义注解的保留策略
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE,//注解仅存在于源码中,在class字节码文件中不包含
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS,// 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME// 注解会在class字节码文件中存在,在运行时可以通过反射获取到
}
1.2 @Target
定义注解的作用目标
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE, //接口、类、枚举、注解
/** Field declaration (includes enum constants) */
FIELD, //字段、枚举的常量
/** Method declaration */
METHOD, //方法
/** Parameter declaration */
PARAMETER, //方法参数
/** Constructor declaration */
CONSTRUCTOR, //构造函数
/** Local variable declaration */
LOCAL_VARIABLE,//局部变量
/** Annotation type declaration */
ANNOTATION_TYPE, //注解
/** Package declaration */
PACKAGE //包
}
1.3 @Documented
说明该注解将被包含在javadoc中
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
1.4 @Inherited
说明子类可以继承父类中的该注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
2.关于@inherited
上一篇博客,对于@Inherited 没有理解好,在这里又学习了一下
感谢这篇博客的分享:
http://blog.csdn.net/wbchn/article/details/3445541
http://blog.csdn.net/meconsea/article/details/3044816
自定义的注解:
package org.ygy.annotation.lesson02;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Table {
public String name();
}
package org.ygy.annotation.lesson02;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Description {
public String value() default "nothing";
}
package org.ygy.annotation.lesson02;
@Table(name = "t_blog")
public class BlogEntity {
private Long id;
private String title;
@Description("获取ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Description
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
package org.ygy.annotation.lesson02;
public class WordBlogEntity extends BlogEntity {
private String word;
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
}
package org.ygy.annotation.lesson02;
public class PictureBlogEntity {
}
测试方法:
package org.ygy.annotation.lesson02;
import java.lang.reflect.Method;
public class InheritedTest {
public static <T> boolean validateClassInherited(Class<T> target) {
if(target.isAnnotationPresent(Table.class)) {
Table table = target.getAnnotation(Table.class);
System.out.println(target.getSimpleName() + ":" + table.name());
return true;
}
return false;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static Object validateMehodInherited(Object obj) {
try {
Class cls = obj.getClass();
//temp
Method m = cls.getMethod("getTitle", new Class[]{});
if(m.isAnnotationPresent(Description.class)) {
System.out.println("OK. ");
}
while (cls != null) {
Method[] methods = cls.getDeclaredMethods();
for(Method method : methods) {
if(method.isAnnotationPresent(Description.class)) {
Description desc = method.getAnnotation(Description.class);
System.out.println(cls.getSimpleName() + "--" + method.getName() + ":" + desc.value());
}
}
cls = cls.getSuperclass();
}
} catch (Exception ex) {
return null;
}
return null;
}
public static void main(String[] args) {
//验证Class上的注解是否可以继承
if(validateClassInherited(BlogEntity.class)) {
System.out.println("BlogEntity OK");
}
if(validateClassInherited(WordBlogEntity.class)) {
System.out.println("WordBlogEntity OK");
}
if(validateClassInherited(PictureBlogEntity.class)) {
System.out.println("wrong");
}
//验证方法上的注解是否可以继承
validateMehodInherited(new BlogEntity());
validateMehodInherited(new WordBlogEntity());
}
}
通过上面的测试,可以总结出:
在注解上添加@Inherited注解,则该注解可以被继承,上面测试了标注在类上,和方法上
只要子类没有重写父类的方法,或者实现父类的抽象方法,在子类中,是可以被继承的。
自定义注解系列:
自定义注解(一)
自定义注解(二)