我正在尝试为我的应用程序创建一个Version
类,它将在加载时读取清单中的版本号,然后仅引用Version.MAJOR
,以及其他我需要的地方。但是,我遇到了这样的问题。这是我目前的代码:
public class Version {
public static final int APPCODE;
public static final int MAJOR;
public static final int MINOR;
public static final char RELEASE;
public static final int BUILD;
static {
try {
Class clazz = Version.class;
String className = clazz.getSimpleName() + ".class";
String classPath = clazz.getResource(className).toString();
if (classPath.startsWith("jar")) {
String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) + "/META-INF/MANIFEST.MF";
Manifest manifest = new Manifest(new URL(manifestPath).openStream());
Attributes attr = manifest.getMainAttributes();
APPCODE = Integer.parseInt(attr.getValue("APPCODE"));
MAJOR = Integer.parseInt(attr.getValue("MAJOR"));
MINOR = Integer.parseInt(attr.getValue("MINOR"));
RELEASE = attr.getValue("RELEASE").charAt(0);
BUILD = Integer.parseInt(attr.getValue("BUILD"));
}
} catch (IOException e) {
System.exit(9001);
}
}
}
它不会编译,因为static final
变量可能没有被初始化(例如,如果加载了错误的清单或加载它的异常),我无法弄清楚正确的程序要做什么这是。
阅读this问题让我有了一些不使用public static final
的见解。我应该使用带有getter方法的public static
吗?
答案 0 :(得分:6)
如果您确保始终只分配final
个字段一次,编译器会很高兴:
public class Version {
public static final int APPCODE;
public static final int MAJOR;
public static final int MINOR;
public static final char RELEASE;
public static final int BUILD;
static {
int appcode = 0;
int major = 0;
int minor = 0;
char release = 0;
int build = 0;
try {
Class clazz = Version.class;
String className = clazz.getSimpleName() + ".class";
String classPath = clazz.getResource(className).toString();
if (classPath.startsWith("jar")) {
String manifestPath = classPath.substring(0,
classPath.lastIndexOf("!") + 1)
+ "/META-INF/MANIFEST.MF";
Manifest manifest = new Manifest(
new URL(manifestPath).openStream());
Attributes attr = manifest.getMainAttributes();
appcode = Integer.parseInt(attr.getValue("APPCODE"));
major = Integer.parseInt(attr.getValue("MAJOR"));
minor = Integer.parseInt(attr.getValue("MINOR"));
release = attr.getValue("RELEASE").charAt(0);
build = Integer.parseInt(attr.getValue("BUILD"));
}
} catch (IOException e) {
System.exit(9001);
}
APPCODE = appcode;
MAJOR = major;
MINOR = minor;
RELEASE = release;
BUILD = build;
}
}
答案 1 :(得分:3)
我会:
答案 2 :(得分:0)
如果您使用public final
字段,则必须指定默认值,因为这些是常量。将可见性更改为private并删除最终修饰符并提供getter / setter。这应该是解决问题的最佳方法。
答案 3 :(得分:0)
您可以删除处理从Version类读取清单的代码块,并将其放入单独的类中 - 例如(ManifestReader) - 并使用构造函数中的实际值直接初始化版本实例。
我会将“public static final”更改为“private final”(非静态),因为如果您有多个Version类实例,则必须拥有自己的appcode,major minor等!!
旁边提供getter()来访问私有的最终字段!