搜尋此網誌

2009年12月2日 星期三

Java Annotation



  • 在Java 1.5 ,annotation data可以在runtime and compile-time處理




  • 紫色的字是Marker Annotation的例子





    public class Annotation {


    }
    class A{

    @Deprecated

    public void test(){

    }
    }




  • Annotation Type是annotations的藍圖,宣告Annotation Type類似宣告interface,只是在interface前面多加了@符號:


     

    public @interface TestAnnotationType {

    String printSomthing();
    }




  • Annotation Type的元素是用方法來定義,這個方法不可以傳入參數,也不可以丟出例外,而回傳值必須是基本型別,
    String, Class, enums, annotations, 以及以上型別的陣列,方法也可以有預設值.


     


    public @interface TestAnnotation {

    String sayHello();
    String defaultSayHello() default "hello";
    }





  • Annotation可以提供額外的資訊給程式使用,可以在compile的時候設定deprecated method展示出warning messages,或是說利用annotation
    讓一些tools產生程式碼,或是說在執行時期把值(Value)傳給method使用.





  • Annotation可以用在class,interface,method,還有field





  • Java5提供了metadata的能力,可以讓你自己定義annotation type.






  • 一個沒有元素的Annotation type被稱為Marker annotation type.




    public @interface TestAnnotation {


    }




  • Marker annotation type的使用上可以省略{},如下例:





    public @interface TestAnnotation {


    }
    @TestAnnotation
    class Test1 { }





  • 單一元素的annotation type可以直接給值,如下例:






    public @interface TestAnnotation {

    String value();
    }
    @TestAnnotation ("Test")
    class Test1 { }





  • annotation 是一種特別的修飾子,它可以放在任何修飾子(諸如public ,privte,protected,等等)可以放的地方,而annotations的值只可以是編譯時期常數.






Annotation的整理













import java.lang.annotation.*;
import java.lang.reflect.Method;


@Retention(RetentionPolicy.RUNTIME) //告訴Jvm可以在執行時期讀取
@Target(ElementType.METHOD)//這個annotation type只可以用在method
public @interface Test {
}

class Foo {
@Test public static void m1() { }
public static void m2() { }
@Test public static void m3() {
throw new RuntimeException("Boom");
}
public static void m4() { }
@Test public static void m5() { }
public static void m6() { }
@Test public static void m7() {
throw new RuntimeException("Crash");
}
public static void m8() { }
}

class RunTest {

public static void main(String[] args) throws Exception {
String[]ar={"Foo"};
int passed = 0, failed = 0;
for (Method m : Class.forName(ar[0]).getMethods()) {
if (m.isAnnotationPresent(Test.class)) {//依次取出annotation type為Test的method
try {
m.invoke(null);
passed++;
} catch (Throwable ex) {//如果有丟出exception就算失敗
System.out
.printf("Test %s failed: %s %n", m, ex.getCause());
failed++;
}
}
}
System.out.printf("Passed: %d, Failed %d%n", passed, failed);
}
}



參考連結:
Java Guide

Java存取修飾子


有兩種等級的存取控制:


類別等級(class level)包含了:public, or default (no modifier).


成員等級(member level)包含了:public, private, protected, or default (no modifier).


以下table展示了每一個修飾子可以存取的成員:


















































修飾子

Package內,類別本身

Package內,不同類別之間

不同Package內的子類別

所有類別




public


Y

Y

Y

Y




protected


Y

Y

Y

N



no modifier

Y

Y

N

N




private


Y

N

N

N












第一欄可解讀為:

Package內,類別本身可存取(可以看到)的成員為private,protected,default,public





package One;
public class SuperClassA {
public int a=1;
protected int b=2;
int c=3;
private int d=4;
public static void main(String[]args){
System.out.println(new SuperClassA().a);
System.out.println(new SuperClassA().b);
System.out.println(new SuperClassA().c);
System.out.println(new SuperClassA().d);

}
}




第二欄可解讀為:

Package內,不同類別之間可存取(可以看到)的成員為protected,default,public





package One;

public class SuperClassA {

public int a=1;
protected int b=2;
int c=3;
private int d=4;
public static void main(String[]args){

System.out.println(new B().a);
System.out.println(new B().b);
System.out.println(new B().c);
//compile-error:System.out.println(new B().d);

}
}
class B{


public int a=1;
protected int b=2;
int c=3;
private int d=4;


}


第三欄可解讀為:

不同Package內的子類別,可存取(可以看到)的成員為protected,public兩者





package Two;
import One.SuperClassA;

class SubOfA extends SuperClassA {

public SubOfA(){
System.out.println(super.a);
System.out.println(super.b);
//compile Error--->System.out.println(super.c);
//compile Error--->System.out.println(super.d);
}

}



第四欄可解讀為:

所有類別皆可存取(可以看到)的成員只有public





package Two;
import One.SuperClassA;

public class OtherClass {
public static void main(String[]args){
System.out.println(new SuperClassA().a);
//compile error--->System.out.println(new Alpha().b);
//compile error--->System.out.println(new Alpha().c);
//compile error--->System.out.println(new Alpha().d);

}

}



work

中国語も日本語と英語も、とともに勉強した方がいいと思います, やはり、international時代が来るんだ。.しかし業務なんかの仕事はやりたくない