package-info.java的使用
阿新 • • 發佈:2018-11-30
一.引入
上文中,提到了註解類JyzTargetPackage可以定義為@Target(ElementType.PACKAGE),可是在被註解類裡我無論怎麼加,編譯器都報錯,於是引入了package-info.java這個檔案。
二.建立package-info.java
- "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."勾上就行了。
- 如果不幸的是你已經建立了這個包並在裡面定義了很多類,而eclispe又是不能直接建立一個package-info.java檔案的。只能在包對應資料夾裡,手動建立一個package-info.java,寫上包名,最後重新整理eclispe即可。
三.package-info.java的作用
- "Package annotations must be in file package-info.java",package-info.java為我們提供了包註解的地方。JyzTargetPackage(http://zy19982004.iteye.com/blog/1979208
- 提供包級別的類(或介面),這些類(或介面)只有本包裡才能訪問,即使是子包也不能訪問。
- 提供包的整體註釋說明。
package-info.java
Java程式碼- /**
- * <b>package-info不是平常類,其作用有三個:</b><br>
- * 1、為標註在包上Annotation提供便利;<br>
- * 2、宣告包的私有類和常量;<br>
- * 3、提供包的整體註釋說明。<br>
- *
- * @author [email protected]
- */
- @JyzTargetPackage(version="1.0")
- package com.jyz.study.jdk.annotation;
- class PackageInfo{
- public void common(){
- System.out.println("sa");
- }
- }
- class PackageInfoGeneric<T extends Throwable>{
- private T obj;
- public void set(T obj){
- this.obj = obj;
- }
- public void common(){
- System.out.println(obj + "sa");
- }
- }
- interface packageInfoInteger{
- public void test();
- }
- class PackageConstants{
- public static final String ERROE_CODE = "100001";
- }
TestPackageInfo.java
Java程式碼- package com.jyz.study.jdk.annotation;
- import java.io.IOException;
- /**
- * 測試package-info.java檔案的作用
- * 1、為標註在包上Annotation提供便利;<br>
- * 2、宣告包的私有類和常量;<br>
- * @author [email protected]
- *
- */
- public class TestPackageInfo {
- public static void main(String[] args) {
- //1
- Package p = Package.getPackage("com.jyz.study.jdk.annotation");
- if(p != null && p.isAnnotationPresent(JyzTargetPackage.class)){
- JyzTargetPackage nav = p.getAnnotation(JyzTargetPackage.class);
- if(nav != null){
- System.out.println("package version:" + nav.version());
- }
- }
- //2
- PackageInfo packageInfo = new PackageInfo();
- packageInfo.common();
- //泛型也能很好的工作,在pakcage-info.java裡定義的類和普通類沒什麼區別
- PackageInfoGeneric<Exception> packageInfoGeneric = new PackageInfoGeneric<Exception>();
- packageInfoGeneric.set(new IOException("device io"));
- packageInfoGeneric.common();
- Sub sub = new Sub();
- sub.test();
- System.out.println(PackageConstants.ERROE_CODE);
- }
- }
- class Sub implements packageInfoInteger{
- @Override
- public void test() {
- System.out.println("sub");
- }
- }
- console output:
- package version:1.0
- sa
- java.io.IOException: device iosa
- sub
- 100001
需要注意兩點
- package-info.java裡不能宣告public class(或 interface)
- 剛開始p.isAnnotationPresent(JyzTargetPackage.class)返回false,後來找到原因JyzTargetPackage沒有加上@Retention(RetentionPolicy.RUNTIME)。
@Inherited的使用
@Inherited:允許子類繼承父類的註解。
二.程式碼
Java程式碼- @Target(ElementType.TYPE)
- @Retention(RetentionPolicy.RUNTIME)
- @Inherited
- public @interface DBTable {
- public String name() default "";
- }
- @Target(ElementType.TYPE)
- @Retention(RetentionPolicy.RUNTIME)
- public @interface DBTable2 {
- public String name() default "";
- }
- package com.jyz.study.jdk.reflect;
- import java.util.Arrays;
- import com.jyz.study.jdk.annotation.DBTable;
- import com.jyz.study.jdk.annotation.DBTable2;
- /**
- * 1.演示從Class物件上獲得反射元素Field Method Constructor
- * 2.演示AnnotatedElement介面的四個方法
- * @author [email protected]
- *
- */
- public class DeclaredOrNot {
- public static void main(String[] args) {
- Class<Sub> clazz = Sub.class;
- System.out.println("============================Field===========================");
- //public + 繼承
- System.out.println(Arrays.toString(clazz.getFields()));
- //all + 自身
- System.out.println(Arrays.toString(clazz.getDeclaredFields()));
- System.out.println("============================Method===========================");
- //public + 繼承
- System.out.println(Arrays.toString(clazz.getMethods()));
- //all + 自身
- System.out.println(Arrays.toString(clazz.getDeclaredMethods()));
- System.out.println("============================Constructor===========================");
- //public + 自身
- System.out.println(Arrays.toString(clazz.getConstructors()));
- //all + 自身
- System.out.println(Arrays.toString(clazz.getDeclaredConstructors()));
- System.out.println("============================AnnotatedElement===========================");
- //註解DBTable2是否存在於元素上
- System.out.println(clazz.isAnnotationPresent(DBTable2.class));
- //如果存在該元素的指定型別的註釋DBTable2,則返回這些註釋,否則返回 null。
- System.out.println(clazz.getAnnotation(DBTable2.class));
- //繼承
- System.out.println(Arrays.toString(clazz.getAnnotations()));
- //自身
- System.out.println(Arrays.toString(clazz.getDeclaredAnnotations()));
- }
- }
- @DBTable
- class Super{
- private int superPrivateF;
- public int superPublicF;
- public Super(){
- }
- private int superPrivateM(){
- return 0;
- }
- public int superPubliceM(){
- return 0;
- }
- }
- @DBTable2
- class Sub extends Super{
- private int subPrivateF;
- public int subPublicF;
- private Sub(){
- }
- public Sub(int i){
- }
- private int subPrivateM(){
- return 0;
- }
- public int subPubliceM(){
- return 0;
- }
- }
- console output:
- ============================Field===========================
- [public int com.jyz.study.jdk.reflect.Sub.subPublicF, public int com.jyz.study.jdk.reflect.Super.superPublicF]
- [private int com.jyz.study.jdk.reflect.Sub.subPrivateF, public int com.jyz.study.jdk.reflect.Sub.subPublicF]
- ============================Method===========================
- [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()]
- [private int com.jyz.study.jdk.reflect.Sub.subPrivateM(), public int com.jyz.study.jdk.reflect.Sub.subPubliceM()]
- ============================Constructor===========================
- [public com.jyz.study.jdk.reflect.Sub(int)]
- [private com.jyz.study.jdk.reflect.Sub(), public com.jyz.study.jdk.reflect.Sub(int)]
- ============================AnnotatedElement===========================
- true
- @com.jyz.study.jdk.annotation.DBTable2(name=)
- [@com.jyz.study.jdk.annotation.DBTable(name=), @com.jyz.study.jdk.annotation.DBTable2(name=)]
- [@com.jyz.study.jdk.annotation.DBTable2(name=)]
三.程式碼說明
- 程式碼演示了從Class物件上獲得反射元素Field Method Constructor時get*和getDeclared*的區別。
- 程式碼演示了AnnotatedElement介面的四個方法。
- java.lang.reflect.AnnotatedElement表示可以被註解的元素。它只有四個方法,參考程式碼DeclaredOrNot.java。
- 當我使用clazz.getAnnotations()時,我期望得到控制檯打印出來的內容,但實際上卻只得到了[@com.jyz.study.jdk.annotation.DBTable2(name=)],後來發現是DBTable裡沒有宣告@Inherited。