Java step by step(3): Annotation
About Annotation
Java 5引入了Annotation, 這極大減輕了開發(fā)的負(fù)擔(dān),不用寫很多的代碼,只需要在代碼中加入一些"tag"就可以了,這個(gè)很符合聲明式編程(declarative programming)的思想。
當(dāng)然有個(gè)問題還是要問的,雖然作為使用annotation的開發(fā)者來說,不用考慮Annotation最后究竟會(huì)被怎樣執(zhí)行,只要在需要使用Annotation的地方tag一下就可以,但是很顯然這個(gè)只是把問題處理地點(diǎn)轉(zhuǎn)移了而已,終歸是需要有人來處理的,不然,這個(gè)Annotation就沒有任何意義了。
可以想見,很多JDK提供的annotation, JVM或者編譯器肯定是要負(fù)責(zé)解釋處理這些anntation的。如果使用一些framework提供的annotation, 自然這些framework會(huì)提供解釋執(zhí)行這些annotation的代碼實(shí)現(xiàn),否則JVM怎么可能知道如何去解釋這些tag呢。那么究竟如何去識(shí)別代碼中哪些地方使用了annotation呢,很容易想到可以運(yùn)用reflection來實(shí)現(xiàn)。
所以,annotation看起來很神秘,其實(shí)只是借助了reflection,將相關(guān)的代碼實(shí)現(xiàn)處理邏輯封閉在一個(gè)地方,從而使得運(yùn)用這些annoation的代碼不需要重復(fù)實(shí)現(xiàn)這些功能,從而簡化了工作量。
The Rules of Defining Java Annotation Types
// MyAnnotation.java@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation {
public String doSomething() default "do something";
public String date();
}
上面是一個(gè)簡單的Annotation定義,Annotation的定義很特別,很像interface,不過需要在interface前面加個(gè)@符號(hào)。另外annotation中定義的method (attribute) 不能是private的,不能接受參數(shù),不能有throws語句,返回值的類型必須是如下幾種之一:
1)primitives
2) ?String
3) ?Class
4) Enum
5) Array of the above types
Java Annotation Types
Java 支持兩種Annotation類型:
1) 簡單類型:這種annotation只能用于其它c(diǎn)ode,不能用于annotation 類型。
2)Meta Annotation: 這種annotation是用于annotation type的,也就是annotation of annotation.
Out-of-the-box Simple Annotation Types in JDK
JDK提供了3個(gè)簡單類型的annotations, 包括:
1) Override
@Target(ElementType.METHOD)@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
可以看到Override只能用于method, 而且retention級(jí)別是SOURCE。這個(gè)Annotation的好處在于可以幫助我們快速發(fā)現(xiàn)問題,如果把toString寫成了toString1,編譯器會(huì)給出錯(cuò)誤提示,這樣就不要等到運(yùn)行的時(shí)候發(fā)現(xiàn)出錯(cuò)了。
2) Deprecated
@Documented@Retention(RetentionPolicy.RUNTIME)
public @interface Deprecated {
}
如果一個(gè)方法或者變量被標(biāo)示成Deprecated,那就意味著該方法或者變量是不應(yīng)該被使用的,否則的話,編譯器會(huì)報(bào)出警告信息。
3) Suppresswarnings
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
/**
* The set of warnings that are to be suppressed by the compiler in the
* annotated element. Duplicate names are permitted. The second and
* successive occurrences of a name are ignored. The presence of
* unrecognized warning names is <i>not</i> an error: Compilers must
* ignore any warning names they do not recognize. They are, however,
* free to emit a warning if an annotation contains an unrecognized
* warning name.
*
* <p>Compiler vendors should document the warning names they support in
* conjunction with this annotation type. They are encouraged to cooperate
* to ensure that the same names work across multiple compilers.
*/
String[] value();
}
這個(gè)Annotation是讓編譯器忽略某些warning信息。
Out-of-the-box Meta Annotation Types in JDK
JDK提供了如下4種Meta Annotation Types:
1) Target
@Documented@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
這個(gè)Annotation用來標(biāo)示定義的annotation類型可以用在哪些類型的元素上,包括如下幾種....
-- @Target(ElementType.TYPE)
-- @Target(ElementType.FIELD) : public attributes of the class
-- @Target(ElementType.METHOD)
-- @Target(ElementType.PARAMETER)
-- @Target(ElementType.CONSTRUCTOR)
-- @Target(ElementType.LOCAL_VARIABLE)
-- @Target(ElementType.ANNOTATION_TYPE)
2) Retention
@Documented@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
這個(gè)Annotation表示定義的annotation會(huì)retention的時(shí)間,有如下三種值:
-- RententionPolicy.SOURCE: retained at the source level, ignored by the compiler
-- RententionPolicy.CLASS: retained by the compiler, ignored by the VM
-- RententionPolicy.RUNTIME: retained by the VM, can be read only at run-time.
3) Documented
@Documented@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
表示定義的annotation type應(yīng)該被javadoc加入到生成的document中的。
4) Inherited
/*** Indicates that an annotation type is automatically inherited. If* an Inherited meta-annotation is present on an annotation type* declaration, and the user queries the annotation type on a class* declaration, and the class declaration has no annotation for this type,* then the class's superclass will automatically be queried for the* annotation type. This process will be repeated until an annotation for this* type is found, or the top of the class hierarchy (Object)* is reached. If no superclass has an annotation for this type, then* the query will indicate that the class in question has no such annotation.** <p>Note that this meta-annotation type has no effect if the annotated* type is used to annotate anything other than a class. Note also* that this meta-annotation only causes annotations to be inherited* from superclasses; annotations on implemented interfaces have no* effect.** @author Joshua Bloch* @since 1.5*/@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
A Simple Example
定義一個(gè)簡單的Annotation Type -- MyAnnoation
// MyAnnotation.java@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation {
public String doSomething() default "do something";
public String date();
}
通過Reflection來獲取annotation定義的field...
// MainTest.javapublic class MainTest {
@MyAnnotation(doSomething = "Test Annotation", date = "2011-08-01")
public String annotationTest;
public void testAnnotation() {
Class aClass = MainTest.class;
try {
Field aField = aClass.getField("annotationTest");
MyAnnotation myAnnotation = aField.getAnnotation(MyAnnotation.class);
annotationTest = myAnnotation.doSomething() + " on " + myAnnotation.date();
System.out.println(this.annotationTest);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
new MainTest().testAnnotation();
}
}
轉(zhuǎn)載于:https://www.cnblogs.com/fangwenyu/archive/2011/08/01/2124310.html
新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎(jiǎng)!定制產(chǎn)品紅包拿不停!總結(jié)
以上是生活随笔為你收集整理的Java step by step(3): Annotation的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: T-SQL查询-逻辑查询处理
- 下一篇: 从一个基础Javascript面试题谈起