1. 程式人生 > >package-info.java的使用

package-info.java的使用

一.引入 

     上文中,提到了註解類JyzTargetPackage可以定義為@Target(ElementType.PACKAGE),可是在被註解類裡我無論怎麼加,編譯器都報錯,於是引入了package-info.java這個檔案。

 

二.建立package-info.java

  1. "I found that when you create a new package in eclispe there is a check box to check if you want a package-info.java."勾上就行了。
  2. 如果不幸的是你已經建立了這個包並在裡面定義了很多類,而eclispe又是不能直接建立一個package-info.java檔案的。只能在包對應資料夾裡,手動建立一個package-info.java,寫上包名,最後重新整理eclispe即可。

 

三.package-info.java的作用

 

  1. "Package annotations must be in file package-info.java",package-info.java為我們提供了包註解的地方。JyzTargetPackage(http://zy19982004.iteye.com/blog/1979208
    )苦苦尋找終於找到地方了。
  2. 提供包級別的類(或介面),這些類(或介面)只有本包裡才能訪問,即使是子包也不能訪問。
  3. 提供包的整體註釋說明。

 package-info.java

Java程式碼   收藏程式碼
  1. /**   
  2.  * <b>package-info不是平常類,其作用有三個:</b><br>   
  3.  * 1、為標註在包上Annotation提供便利;<br>   
  4.  * 2、宣告包的私有類和常量;<br>   
  5.  * 3、提供包的整體註釋說明。<br>   
  6.  *  
  7.  * @author [email protected]  
  8. */   
  9. @JyzTargetPackage(version="1.0")  
  10. package com.jyz.study.jdk.annotation;  
  11.   
  12. class PackageInfo{  
  13.     public void common(){  
  14.         System.out.println("sa");  
  15.     }  
  16. }  
  17.   
  18. class PackageInfoGeneric<T extends Throwable>{  
  19.     private T obj;  
  20.     public void set(T obj){  
  21.         this.obj = obj;  
  22.     }  
  23.     public void common(){  
  24.         System.out.println(obj + "sa");  
  25.     }  
  26. }  
  27.   
  28. interface packageInfoInteger{  
  29.     public void test();  
  30. }  
  31.   
  32. class PackageConstants{  
  33.     public static final String ERROE_CODE = "100001";     
  34. }  

 

 

TestPackageInfo.java

Java程式碼   收藏程式碼
  1. package com.jyz.study.jdk.annotation;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. /** 
  6.  * 測試package-info.java檔案的作用 
  7.  * 1、為標註在包上Annotation提供便利;<br>   
  8.  * 2、宣告包的私有類和常量;<br>   
  9.  * @author [email protected] 
  10.  * 
  11.  */  
  12. public class TestPackageInfo {  
  13.   
  14.     public static void main(String[] args) {  
  15.         //1  
  16.         Package p = Package.getPackage("com.jyz.study.jdk.annotation");  
  17.         if(p != null && p.isAnnotationPresent(JyzTargetPackage.class)){  
  18.             JyzTargetPackage nav = p.getAnnotation(JyzTargetPackage.class);  
  19.             if(nav != null){   
  20.                 System.out.println("package version:" + nav.version());  
  21.             }  
  22.         }  
  23.           
  24.         //2  
  25.         PackageInfo packageInfo = new PackageInfo();  
  26.         packageInfo.common();  
  27.           
  28.         //泛型也能很好的工作,在pakcage-info.java裡定義的類和普通類沒什麼區別  
  29.         PackageInfoGeneric<Exception> packageInfoGeneric = new PackageInfoGeneric<Exception>();  
  30.         packageInfoGeneric.set(new IOException("device io"));  
  31.         packageInfoGeneric.common();  
  32.           
  33.           
  34.         Sub sub = new Sub();  
  35.         sub.test();  
  36.           
  37.         System.out.println(PackageConstants.ERROE_CODE);  
  38.     }  
  39. }  
  40.   
  41. class Sub implements packageInfoInteger{  
  42.       
  43.     @Override  
  44.     public void test() {  
  45.         System.out.println("sub");  
  46.     }  
  47.       
  48. }  
  49.   
  50.   
  51. console output:  
  52. package version:1.0  
  53. sa  
  54. java.io.IOException: device iosa  
  55. sub  
  56. 100001  

 

  需要注意兩點

  1. package-info.java裡不能宣告public class(或 interface)
  2. 剛開始p.isAnnotationPresent(JyzTargetPackage.class)返回false,後來找到原因JyzTargetPackage沒有加上@Retention(RetentionPolicy.RUNTIME)。

 

 

 

 

@Inherited的使用

 

[email protected]

     @Inherited:允許子類繼承父類的註解。

 

二.程式碼

Java程式碼   收藏程式碼
  1. @Target(ElementType.TYPE)  
  2. @Retention(RetentionPolicy.RUNTIME)  
  3. @Inherited  
  4. public @interface DBTable {   
  5.     public String name() default "";      
  6. }  
  7.   
  8.   
  9. @Target(ElementType.TYPE)  
  10. @Retention(RetentionPolicy.RUNTIME)  
  11. public @interface DBTable2 {  
  12.     public String name() default "";      
  13. }  
  14.   
  15.   
  16. package com.jyz.study.jdk.reflect;  
  17.   
  18. import java.util.Arrays;  
  19.   
  20. import com.jyz.study.jdk.annotation.DBTable;  
  21. import com.jyz.study.jdk.annotation.DBTable2;  
  22.   
  23. /** 
  24.  * 1.演示從Class物件上獲得反射元素Field Method Constructor 
  25.  * 2.演示AnnotatedElement介面的四個方法 
  26.  * @author [email protected] 
  27.  * 
  28.  */  
  29. public class DeclaredOrNot {  
  30.   
  31.     public static void main(String[] args) {  
  32.         Class<Sub> clazz = Sub.class;  
  33.         System.out.println("============================Field===========================");  
  34.         //public + 繼承  
  35.         System.out.println(Arrays.toString(clazz.getFields()));  
  36.         //all + 自身  
  37.         System.out.println(Arrays.toString(clazz.getDeclaredFields()));  
  38.           
  39.         System.out.println("============================Method===========================");  
  40.         //public + 繼承  
  41.         System.out.println(Arrays.toString(clazz.getMethods()));  
  42.         //all + 自身  
  43.         System.out.println(Arrays.toString(clazz.getDeclaredMethods()));  
  44.           
  45.         System.out.println("============================Constructor===========================");  
  46.         //public + 自身  
  47.         System.out.println(Arrays.toString(clazz.getConstructors()));  
  48.         //all + 自身  
  49.         System.out.println(Arrays.toString(clazz.getDeclaredConstructors()));  
  50.           
  51.           
  52.         System.out.println("============================AnnotatedElement===========================");  
  53.         //註解DBTable2是否存在於元素上  
  54.         System.out.println(clazz.isAnnotationPresent(DBTable2.class));  
  55.         //如果存在該元素的指定型別的註釋DBTable2,則返回這些註釋,否則返回 null。  
  56.         System.out.println(clazz.getAnnotation(DBTable2.class));  
  57.         //繼承  
  58.         System.out.println(Arrays.toString(clazz.getAnnotations()));  
  59.         //自身  
  60.         System.out.println(Arrays.toString(clazz.getDeclaredAnnotations()));  
  61.     }  
  62. }  
  63.   
  64. @DBTable  
  65. class Super{  
  66.     private int superPrivateF;  
  67.     public int superPublicF;  
  68.       
  69.     public Super(){  
  70.     }  
  71.       
  72.     private int superPrivateM(){  
  73.         return 0;  
  74.     }  
  75.     public int superPubliceM(){  
  76.         return 0;  
  77.     }  
  78. }  
  79.   
  80. @DBTable2  
  81. class Sub extends Super{  
  82.     private int subPrivateF;  
  83.     public int subPublicF;  
  84.       
  85.     private Sub(){  
  86.     }  
  87.     public Sub(int i){  
  88.     }  
  89.       
  90.     private int subPrivateM(){  
  91.         return 0;  
  92.     }  
  93.     public int subPubliceM(){  
  94.         return 0;  
  95.     }  
  96. }  
  97.   
  98.   
  99.   
  100. console output:  
  101. ============================Field===========================  
  102. [public int com.jyz.study.jdk.reflect.Sub.subPublicF, public int com.jyz.study.jdk.reflect.Super.superPublicF]  
  103. [private int com.jyz.study.jdk.reflect.Sub.subPrivateF, public int com.jyz.study.jdk.reflect.Sub.subPublicF]  
  104. ============================Method===========================  
  105. [public int com.jyz.study.jdk.reflect.Sub.subPubliceM(), public int com.jyz.study.jdk.reflect.Super.superPubliceM(), public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public final void java.lang.Object.wait() throws java.lang.InterruptedException, public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]  
  106. [private int com.jyz.study.jdk.reflect.Sub.subPrivateM(), public int com.jyz.study.jdk.reflect.Sub.subPubliceM()]  
  107. ============================Constructor===========================  
  108. [public com.jyz.study.jdk.reflect.Sub(int)]  
  109. [private com.jyz.study.jdk.reflect.Sub(), public com.jyz.study.jdk.reflect.Sub(int)]  
  110. ============================AnnotatedElement===========================  
  111. true  
  112. @com.jyz.study.jdk.annotation.DBTable2(name=)  
  113. [@com.jyz.study.jdk.annotation.DBTable(name=), @com.jyz.study.jdk.annotation.DBTable2(name=)]  
  114. [@com.jyz.study.jdk.annotation.DBTable2(name=)]  

 

三.程式碼說明

  1. 程式碼演示了從Class物件上獲得反射元素Field Method Constructor時get*和getDeclared*的區別。
  2. 程式碼演示了AnnotatedElement介面的四個方法。
    1. java.lang.reflect.AnnotatedElement表示可以被註解的元素。它只有四個方法,參考程式碼DeclaredOrNot.java。
    2. 當我使用clazz.getAnnotations()時,我期望得到控制檯打印出來的內容,但實際上卻只得到了[@com.jyz.study.jdk.annotation.DBTable2(name=)],後來發現是DBTable裡沒有宣告@Inherited。