简体   繁体   English

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

[英]Initializing public static final variables in constructor

I'm trying to make a Version class for my app that will read version numbers from the manifest at load time and then just reference for example Version.MAJOR and such wherever I need it elsewhere. 我正在尝试为我的应用程序创建一个Version类,它将在加载时从清单中读取版本号,然后仅引用Version.MAJOR等我在其他地方需要的地方。 However, I'm having issues doing so. 但是,我遇到了这样的问题。 Here's my current code: 这是我目前的代码:

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

It won't compile, because the static final variables might not be initialized (for example if the wrong manifest is loaded or there's an exception loading it) and I can't figure out what the correct procedure to do this is. 它不会编译,因为static final变量可能没有被初始化(例如,如果加载了错误的清单或加载它的异常),我无法弄清楚正确的程序是做什么的。

Reading this question has given me some insight to not use public static final . 阅读这个问题给了我一些不使用public static final见解。 Should I rather be using public static with getter methods? 我应该使用getter方法使用public static吗?

If you make sure that you always assign to the final fields exactly once, the compiler will be happy: 如果确保始终只分配一次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;
    }
}

I would: 我会:

  • remove the final modifiers 删除最终修饰符
  • reduce the visibility from public to private. 降低从公共到私人的可见性。
  • provide (static) getters for the needed fields 为所需字段提供(静态)getter

If you are using public final fields you have to assign default values because those are constants. 如果您使用public final字段,则必须分配默认值,因为这些是常量。 Change the visibility to private and remove the final modifier and provide getters/setters. 将可见性更改为private并删除最终修饰符并提供getter / setter。 This should be the best way to solve your problem. 这应该是解决问题的最佳方法。

you can remove block of code dealing with reading manifest from Version class and put it into a separate class - for instance (ManifestReader) - and initialize version instances directly with actual values in constructor. 您可以从Version类中删除处理读取清单的代码块,并将其放入单独的类中 - 例如(ManifestReader) - 并使用构造函数中的实际值直接初始化版本实例。

i would change the "public static final" to "private final" (not static) because if you have more than one instance of Version class all must have their own appcode, major minor etc !! 我会将“public static final”更改为“private final”(非静态),因为如果你有多个Version类的实例,则必须拥有自己的appcode,major minor等!

beside provide getter() to access private final fields! 旁边提供getter()来访问私有的最终字段!

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

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