簡體   English   中英

Java Singleton +內部類錯誤理解

[英]Java Singleton + inner class missunderstand

我在過去的兩個月里一直在編程Java,但我在python和C中經驗過程序員。我知道我因此而犯了錯誤。

我來到這個問題清除警告我在Android工作室的項目。

我使用帶有內部類的Singleton類將所有配置參數保存在一個位置,讓所有其他類訪問它而不需要傳遞配置。

這是我的Singleton的基本代碼

public class syscfg {

    public List<CommData> Commlist;
    public static CommConfigIP4 MyCommConfig;// = new CommConfig();

    private static syscfg instance = null;
    private static boolean ConfigStat = false;

    /** JAVA singleton control methods**/
    protected syscfg(){
        // pues eso

        if(ConfigStat == false){
            Log.i("SD_app_log", "SYSCFG: Module Initialization");
            ConfigStat = true;
            MyCommConfig = new CommConfigIP4();
            init_config();
        }else{
            Log.i("SD_app_log", "SYSCFG:  Module Loaded");
        }
    }

    public static syscfg getInstance(){
        if(instance == null){
            instance = new syscfg();
        }
        return instance;
    }

    public class CommConfigIP4{
        public int discoveryPort = 30303;
        public  byte[] MyMAC;
        public  String MyType = "";
        public  String MyIP;

        public  byte[] getIPbytearray(){
//            byte[] IPout= new byte[4];
            try{
                byte[] IPout = (InetAddress.getByName(MyIP)).getAddress();
                return IPout;
            }catch (Exception e){
                return null;
            }

        }

在我的通訊java文件/類中我有:

public class Communications {

    private syscfg CFid ;
    ...
    public Communications(Context ctx){
        ...
        CFid = syscfg.getInstance();
        init_comms(); //init_comms calls whoami
    }

    private void whoami (){
        ...
        CFid.MyCommConfig.MyType = netint.getName();
        ...
    }
}

所以,當我第一次擁有syscfg中的所有元素(變量,類和方法)時,靜態android工作室會顯示一條警告,說靜態成員通過實例引用訪問。 經過一些研究和文檔后,我發現建議不要使用靜態變量和方法,我試圖將它們全部消除。 但后來我得到了一個nullpointexception錯誤

CFid.MyCommConfig.MyType = netint.getName();

使用調試器,我發現CFid.MyCommConfig = null

我使用單例來避免在syscfg類上使用static並通過實例化訪問而不使用類名。

現在我的單例代碼就像這里發布的CommConfigIP4靜態代碼一樣,我再次發出警告,建議我使用:

syscfg.MyCommConfig.MyType = netint.getName();

而不是使用實例來訪問配置。

這里發生了什么? 我錯過了什么?

謝謝,吉列爾莫

在你的whoami()方法中,你做了這個引用:

CFid.MyCommConfig.MyType = netint.getName();

...但是,“MyCommConfig”是類“syscfg”的靜態屬性,而變量“CFid”是指此類的實例。 換句話說,“syscfg”的所有實例(以及類定義本身)都引用了“MyCommConfig”變量的相同副本(這是靜態的意思)。

因此,通過說“syscfg.MyCommConfig”來引用“MyCommConfig”變量並不那么令人困惑,因為這表明你指的是靜態變量而不是實例1。

順便說一句,您應該考慮遵循標准Java代碼約定來大寫類名和變量,因為這將使您的代碼對其他Java程序員更具可讀性。

您應該將嵌套類聲明為靜態:

public static class CommConfigIP4

然后取消注釋在外部類頂部初始化靜態變量的代碼。

要避免這些警告,您應該以這種方式實現單例。 我更改了一些代碼以使其易於理解:

public class Syscfg {

    public Config getConfig() {
        return c;
    }

    // Obtain the same instance always
    public static Syscfg getInstance() {
        return s == null ? new Syscfg() : s;
    }

    // Important for singleton
    private Syscfg() {
        c = new Config();
    }

    private static Syscfg s;
    private Config c;

    class Config {

        public String[] getConfigs() {
            return configs;
        }

        private String[] configs = {"10.10.10.10", "userName", "userPass"}; 
    }

}

所以,如果你想知道另一個類中使用的配置,例如Test類,那么你可以使用

public class Test {

    public static void main(String[] args) {
        System.out.println(Arrays.toString(Syscfg.getInstance().getConfig().getConfigs()));
    }

}

結果是:[10.10.10.10,userName,userPass]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM