`
Lewiss
  • 浏览: 19619 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Java 打包信息

    博客分类:
  • J2SE
阅读更多
在 java 中,可以在打包是往包里添加包的版本等基本信息,这有助于各版本包之间的协调,在分布式系统中也适用。

在 java 包中添加基本信息有两种方式,一是传统的往包的 MANIFEST.MF 文件中写信息,二是用注解。


1,往 MANIFEST.MF 写信息,包括:
Name 	                The name of the specification.
Specification-Title 	The title of the specification.
Specification-Version 	The version of the specification.
Specification-Vendor 	The vendor of the specification.
Implementation-Title 	The title of the implementation.
Implementation-Version 	The build number of the implementation.
Implementation-Vendor 	The vendor of the implementation.


如,java 的 util 包该文件内容如下:
Name: java/util/
Specification-Title: Java Utility Classes
Specification-Version: 1.2
Specification-Vendor: Sun Microsystems, Inc.
Implementation-Title: java.util
Implementation-Version: build57
Implementation-Vendor: Sun Microsystems, Inc.


该文件在打包时产生,信息由打包者输入。

以上信息将被 Java 虚拟机自动封装到 Package 对象中。假设包中包含 Test 类,那么用如下语句可以获取该包的信息:
Package	myPackage = Test.class.getPackage();
myPackage.getImplementationVersion()
...



2,用注解添加包的基本信息
在 java 中有几种级别的注解,包括变量级、方法级、类级和包级,我们可以添加包注解,并在注解中添加包基本信息。
对于包级注解,java 做了如下规定:
包注解只能用在文件名为 package-info.java 的源文件中,并且该源文件只有包声明的语句,在包声明语句之前添加注解类,如:
@Annotation1(...)
package sample;


当 java 编译器碰到 package-info.java 文件的时候,它会为该文件产生一个名为 package-info.class 的文件,通过反编译可以看到该文件是一个抽象接口,如:
package sample;

@Annotation1(...)
abstract interface package-info{
}


于是在运行过程中就可以通过该接口获取包级注解了。
可以通过 java.lang.Package 对象来获取包级注解,查看该类的源码,可以看到获取某个特定注解过程如下:
应用程序调用 Package 的 getAnnotation 方法
    /**
     * @throws NullPointerException {@inheritDoc}
     * @since 1.5
     */
    public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
        return getPackageInfo().getAnnotation(annotationClass);
    }

getAnnotation 方法再通过 getPackageInfo() 获得由编译器根据 package-info.java 文件产生的 package-info 接口,从而可以获得所有注解信息

    private Class<?> getPackageInfo() {
        if (packageInfo == null) {
            try {
                packageInfo = Class.forName(pkgName + ".package-info", false, loader);
            } catch (ClassNotFoundException ex) {
                // store a proxy for the package info that has no annotations
                class PackageInfoProxy {}
                packageInfo = PackageInfoProxy.class;
            }
        }
        return packageInfo;
    }


下面,写个简单例子,假设所有代码都在包 sample 下。
由上可以知道需要写的类有:
1.注解类:SampleAnnot.java(可以多个)
2.包级注解存放文件:package-info.java
3.我们再写个 Test.java

注解类:SampleAnnot.java,该类只有一个 field,就是 version

package sample;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PACKAGE)
public @interface SampleAnnot {
	String version();
}



-------------------------------------------------------------
package-info.java:该文件只有一行包的声明语句和一行注解

@SampleAnnot(version="1.0")
package sample;

-------------------------------------------------------------
Test.java:该文件获取包对象,并从包对象中获取包的注解信息,关于获取过程请参照上面源码分析

package sample;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		// 获取 SampleAnnot 注解
		SampleAnnot sampleAnnot = Test.class.getPackage().getAnnotation(SampleAnnot.class);
		
		// 打印版本信息
		System.out.println(sampleAnnot.version());
	}

}



分享到:
评论
1 楼 小哥1900 2011-04-26  
楼主有前途~~~~据说楼主在501现在说话都大声了很多啊。

相关推荐

Global site tag (gtag.js) - Google Analytics