簡體   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