之前寫過自定義注解的例子,現在看一看,覺得有些東西還沒有了解透徹,是以打算再重新整理一些會用得到的知識。
感謝下面這些部落格的的分享:
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注解,則該注解可以被繼承,上面測試了标注在類上,和方法上
隻要子類沒有重寫父類的方法,或者實作父類的抽象方法,在子類中,是可以被繼承的。
自定義注解系列:
自定義注解(一)
自定義注解(二)