1. 程式人生 > >另類的package-info.java檔案探討

另類的package-info.java檔案探討

    翻看以前的筆記,看到一個特殊的java檔案:pacakge-info.java,雖然有記錄,但是不全,就嘗試著追蹤一下該問題,分享一下流水賬式的結果。

首先,它不能隨便被建立。在Eclipse中, package-info檔案不能隨便被建立,會報“Type name is notvalid”錯誤,類名無效,Java變數定義規範是:字母、數字、下劃線,還有那個不怎麼常用的$符號(順帶說下,Java是支援中文名稱的變數,習慣挑戰的同學可以嘗試下,分享一下這方面的經驗),這個中劃線可不再之列,那怎麼建立這個檔案呢?

很簡單,用記事本建立一個,然後拷貝進去再改一下就成了,更直接的辦法就是從別的專案中拷貝過來一個,這更方便。

   其次,服務的物件很特殊。一個類是一類或一組事物的描述,比如Dog這個類,就是描述旺財的,那package-info這個類是描述啥的呢?它總要有一個被描述或被陳述的物件,它是描述和記錄本包資訊

    最後,類不能帶有public、private訪問許可權。package-info.java再怎麼特殊,也是一個類檔案,也會被編譯成package-info.class,但是在package-info.java中只能宣告預設訪問許可權的類,也就是友好類。

其實還有幾個特殊的地方,比如不可以繼承,沒有介面,沒有類間關係(關聯、組合、聚合等等)等。

這個檔案的特殊性說完了,那再說說它有什麼作用,它有三個作用:

1、為標註在包上Annotation提供便利;

2、宣告友好類和包常量;

3、提供包的整體註釋說明。

    我們來建立一個專案演示這三個作用,建立一個package-info的Java Project,在com.company包三個類:package-info.java 是我們重點關注的,PkgAnnotation.java是一個標註在包上的註解定義,Client.java模擬業務操作類。其結構如下圖:


為標註在包上Annotation提供便利

     首先定義一個包型別的註解,它只能放置的一個包上:

Java程式碼
  1. /**
  2.  * 定義只能標註在package上的註解
  3. */  
  4. @Target(ElementType.PACKAGE)   
  5. @Retention(RetentionPolicy.RUNTIME)   
  6. public @interface PkgAnnotation {   
  7. }  
/**
 * 定義只能標註在package上的註解
*/
@Target(ElementType.PACKAGE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PkgAnnotation {
}

     再定義一個package-info類,這個是一個特殊的類,先看程式碼:

Java程式碼
  1. @PkgAnnotation  
  2. package com.company;  
@PkgAnnotation
package com.company;

      很簡單,就這麼個檔案,裡面啥都沒有,就這兩句話,沒有class類,沒有常變數宣告。接著寫一個模擬交易類,程式碼如下:

Java程式碼
  1. public class Client {      
  2.     public static void main(String[] args) {   
  3.         //可以通過I/O操作或配置項獲得包名   
  4.         String pkgName = "com.company";        
  5.         Package pkg = Package.getPackage(pkgName);   
  6.         //獲得包上的註解   
  7.         Annotation[] annotations = pkg.getAnnotations();   
  8.         //遍歷註解陣列   
  9.         for(Annotation an:annotations){   
  10.             if(an instanceof PkgAnnotation){   
  11.                 System.out.println("Hi,I'm the PkgAnnotation ,which is be placed on package!");   
  12.                 /*
  13.                  * 註解操作
  14.                  * MyAnnotation myAnn = (PkgAnnotation)an;
  15.                  * 還可以操作該註解包下的所有類,比如初始化,檢查等等
  16.                  * 類似Struts的@Namespace,可以放到包名上,標明一個包的namespace路徑
  17.                  */            
  18.             }   
  19.         }   
  20.     }   
  21. }  
public class Client {	
	public static void main(String[] args) {
		//可以通過I/O操作或配置項獲得包名
		String pkgName = "com.company";		
		Package pkg = Package.getPackage(pkgName);
		//獲得包上的註解
		Annotation[] annotations = pkg.getAnnotations();
		//遍歷註解陣列
		for(Annotation an:annotations){
			if(an instanceof PkgAnnotation){
				System.out.println("Hi,I'm the PkgAnnotation ,which is be placed on package!");
				/*
				 * 註解操作
				 * MyAnnotation myAnn = (PkgAnnotation)an;
				 * 還可以操作該註解包下的所有類,比如初始化,檢查等等
				 * 類似Struts的@Namespace,可以放到包名上,標明一個包的namespace路徑
				 */			
			}
		}
	}
}

      執行結果如下所示:

Hi,I'm the PkgAnnotation ,which is be placed on package!

宣告友好類和包常量

     這個比較簡單,而且很實用,比如一個包中有很多的內部訪問的類或常量,就可以統一的放到package-info類中,這樣就方便,而且集中管理,減少friendly類到處遊走的情況,看例子:

Java程式碼
  1. @PkgAnnotation  
  2. package com.company;   
  3.  //這裡是包類,宣告一個包使用的公共類,強調的是包訪問許可權   
  4. class PkgClass{   
  5.     public void test(){   
  6.     }   
  7. }   
  8. //包常量,只執行包內訪問,適用於分“包”開發   
  9. class PkgConst{   
  10.     static final String PACAKGE_CONST="ABC";   
  11. }  
@PkgAnnotation
package com.company;
 //這裡是包類,宣告一個包使用的公共類,強調的是包訪問許可權
class PkgClass{
	public void test(){
	}
}
//包常量,只執行包內訪問,適用於分“包”開發
class PkgConst{
	static final String PACAKGE_CONST="ABC";
}

  提供包的整體註釋說明

     如果是分“包”開發,也就是說一個包實現一個業務邏輯或功能點、或模組、或元件,則需要對一個包有很好的說明,說明這個包是幹啥的,有啥作用,版本變遷,特別說明等等,如下:

Java程式碼
  1. /**
  2.  * <b>package-info不是平常類,其作用有三個:</b><br>
  3.  * 1、為標註在包上Annotation提供便利;<br>
  4.  * 2、宣告包的私有類和常量;<br>
  5.  * 3、提供包的整體註釋說明。<br> 
  6. */  
  7. package com.company;  
/**
 * <b>package-info不是平常類,其作用有三個:</b><br>
 * 1、為標註在包上Annotation提供便利;<br>
 * 2、宣告包的私有類和常量;<br>
 * 3、提供包的整體註釋說明。<br> 
*/
package com.company;

     通過javadoc生成的API文件如下:


     這與包下放置package.htm沒啥區別,只是package-info可以更好的在程式碼中維護文件的完整性,並且可以實現程式碼與文件同步更新,package.htm也可以做到,不爭論,建議是Java 1.5以上版本都使用package-info.java來註釋。

     與package-info相關的問題

     在專案開發中,可以放置在包上的常用註解有:Struts的@namespace、Hibernate的@FilterDef和@TypeDef等等。在包下,隨便一個類中的包名前加這些註解,Eclipse會提示“Package annotations must be in file package-info.java”,在該包下建立package-info.java檔案,把註解移到這裡即可。

    使用Checkstyle外掛做程式碼檢查時,會報一個警告“Missing package-info.java file.”也是這個package-info檔案惹的禍,在各個包下建立一個即可。

相關推薦

package-info.java檔案探討

    翻看以前的筆記,看到一個特殊的java檔案:pacakge-info.java,雖然有記錄,但是不全,就嘗試著追蹤一下該問題,分享一下流水賬式的結果。 首先,它不能隨便被建立。在Eclipse中, package-info檔案不能隨便被建立,會報“Type name

package-info.java檔案探討 [轉]

翻看以前的筆記,看到一個特殊的java檔案:pacakge-info.java,雖然有記錄,但是不全,就嘗試著追蹤一下該問題,分享一下流水賬式的結果。 首先,它不能隨便被建立。在Eclipse中, package-info檔案不能隨便被建立,會報“Type name

package-info.java的使用

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

eclipse新建package會自動生成package-info.java

今天新建專案,再新建package的過程中發現自動生成了package-info.java,還需要手動刪掉,後來發現是在新建package時,勾選了 create package-info.java的選項,去掉就好啦

如何在命令視窗下編譯執行含有Packagejava檔案

如我們在Eclispe下建立名為Test的專案,新建Package名為test,然後建立HelloWord.java檔案。結構如下: 檔案位置: 那麼如何在CMD下執行呢?方法如下: 在WIN10系統下,編譯完成後,直接執行檔案會報錯。需要返回上一級,輸入

Eclipse 下如何引用一個專案的Java檔案

有關聯的2個專案,有些類是相同的。例如實體類。 如果你採用 Ctrl + C & Ctrl + V 的方式,以後再有改動,2個專案就都需要改動。 怎樣才能只改動一個呢? 答案就是,在一個專案(專案A)中引用另一個專案(專案B)。 右鍵 專案A,點選 Propert

hadoop編譯原始碼報錯:package-info.java: 未結束的字串字面值

compile-core-classes:        [javac] Compiling 386 source files to F:\hadoop\common\trunk\build\classes        [javac] F:\hadoop\common\trunk\build\src\org

PACKAGE-INFO.JAVA 作用及用法詳解

package-info.java對於經常使用外部包的程式設計師來說應該是熟悉陌生人。因為不是專門開發包的程式設計師很少需要關注它,而又常在其他包中看到他,眼很熟。它到底有哪些特性和作用及如何使用呢?程式設計師講究動口不如動手,何不建立一個試試。開啟Eclipse,new class,哦!建立失敗,‘-’

android 建立工程的 package-info.java

一.引入       上文http://zy19982004.iteye.com/blog/1979208中,提到了註解類JyzTargetPackage可以定義為@Target(ElementType.PACKAGE),可是在被註解類裡我無論怎麼加,編譯器都報錯,於是引入

Java中的package-info.java作用

前言   之前在Eclipse中,總是會不小心勾選到這個複選框,之前並沒有怎麼在意這個java檔案,畢竟生成之後只有以下這麼點內容。         而且你也不能直接建立package-info

java 中的package-info.java 的作用小總結

開發十年,就只剩下這套架構體系了! >>>   

使用Java package-info為包服務

Java 中有一個特殊的類:package-info 類,它是專門為本包服務的,為什麼說它特殊呢?主要體現在3 個方面: 它不能隨便被建立 在一般的IDE 中,Eclipse、package-info

Java筆記】一個.java檔案中存在多個的問題

一個.java檔案中可以有很多類。不過注意以下幾點: 1、public 許可權的類只能有一個(也可以一個都沒有,但最多隻有1個) 2、這個.java檔案的檔名必須是public類的類名(一般的情況下,這裡放置main方法是程式的入口。) 3、若這個檔案中沒有public的類,則檔名隨

mac終端下執行java檔案報錯:找不到或無法載入主

由面試題出來的 為了顯示 myStr = 23 這樣的結果,寫出在控制檯輸入的命令 public class MyClass { public static void main(String args[]) { String s1 = args[0]; String s2 = args[

Java NIO使用Files一行程式碼讀取檔案內容

Files類 Files 類是 java.nio 包中的用於操作檔案的類,提供了比 java.io.File 類更便捷的操作。 其中,Files類的 readAllBytes 方法提供了一個讀取所有位元組的方法,可以將讀取結果很方便地賦值給一個 String。 例如以下程式碼,可以用一行程式碼實

Idea不識別java檔案檔案顯示橙色)

解決: 1.點選File  -->  Project Structure 2.Modules 裡 將Content Root刪除再新增 3.重新修改maven設定(非maven專案請跳過此步) File->setting  &

爬蟲:從PDF檔案中爬取表格資料

簡介   本文將展示一個稍微不一樣點的爬蟲。   以往我們的爬蟲都是從網路上爬取資料,因為網頁一般用HTML,CSS,JavaScript程式碼寫成,因此,有大量成熟的技術來爬取網頁中的各種資料。這次,我們需要爬取的文件為PDF檔案。本文將展示如何利用Python的camelot模組

Java 檔案拆分合並工具

/** * 拆分的思路,先把原始檔的所有內容讀取到記憶體中,然後從記憶體中挨個分到子檔案裡 * * @param srcFile * 要拆分的原始檔 路徑 * @param eachSize *

java常用工具(三)—— 檔案讀取的操作

定義常用的檔案型別 public class FileType { /** * 檔案頭型別 */ public static final String XML_FILE = "text/xml;charset=UTF-8"; public static

java檔案路徑問題及Eclipse package,source folder,folder區別及相互轉換

eclipse下,建立一個source folder(我建立的是folder,),名稱為resource,呼叫時 為   "resource/bg.gif" ; //注意resource前面沒有 /" 有/則錯誤 eclipse的相對路徑起始位置位於當前包的根目錄,system.g