Java 打包信息

在 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());
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值