繁体   English   中英

在构造函数中初始化public static final变量

[英]Initializing public static final variables in constructor

我正在尝试为我的应用程序创建一个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变量可能没有被初始化(例如,如果加载了错误的清单或加载它的异常),我无法弄清楚正确的程序是做什么的。

阅读这个问题给了我一些不使用public static final见解。 我应该使用getter方法使用public static吗?

如果确保始终只分配一次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;
    }
}

我会:

  • 删除最终修饰符
  • 降低从公共到私人的可见性。
  • 为所需字段提供(静态)getter

如果您使用public final字段,则必须分配默认值,因为这些是常量。 将可见性更改为private并删除最终修饰符并提供getter / setter。 这应该是解决问题的最佳方法。

您可以从Version类中删除处理读取清单的代码块,并将其放入单独的类中 - 例如(ManifestReader) - 并使用构造函数中的实际值直接初始化版本实例。

我会将“public static final”更改为“private final”(非静态),因为如果你有多个Version类的实例,则必须拥有自己的appcode,major minor等!

旁边提供getter()来访问私有的最终字段!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM