在Java构造函数中添加“this”对Array的引用失败

时间:2009-09-04 10:26:10

标签: java constructor

我绝对不知道为什么以下代码不断抛出NullpointerExceptions。我无法理解或调试它(从较大的类中删除它的代码)......

代码基于“枚举模式”,我希望保留类中包含的所有“常量”的列表/映射(我可能正在使用Reflection,但使用List / Map更容易...)

   public class Country {

        public static final Country SWITZERLAND = new Country("SWITZERLAND");

        private static ArrayList<Country> countries = new ArrayList<Country>();

        private  Country(String constname) {     
             //constname is currently not used (I will use it for a Key in a Map)
            System.out.println(constname);
            System.out.println("Ref debug:"+this);

            //Ad this to the Countries
            Country.countries.add(this);
        }
    }

非常感谢帮助。我在这里缺少什么?

5 个答案:

答案 0 :(得分:5)

静态的

SWITZERLAND可能会在 countries之前初始化,这也是static。因此,countries的构造函数调用中null仍为SWITZERLAND

要强制定义良好的初始化顺序,请使用static块:

public class Country {

    public static final Country SWITZERLAND;

    private static ArrayList<Country> countries;

    static {
        countries = new ArrayList<Country>();
        SWITZERLAND = new Country("SWITZERLAND");
    }
}

答案 1 :(得分:4)

为了扩展Konrad所说的内容,静态变量初始值设定项以文本顺序执行(如JLS section 8.7中所述)。如果您先放置ArrayList,它将起作用:

public class Country {    
    private static ArrayList<Country> countries = new ArrayList<Country>();

    public static final Country SWITZERLAND = new Country("SWITZERLAND");

...

Konrad建议使用静态构造函数来明确指定顺序是一个很好的建议。

您使用的是Java“pre 1.5”吗?如果没有,请使用直接枚举...

答案 2 :(得分:4)

因为我认为这比乔恩所说的更为粗略:

“类型安全枚举模式”已过时!

除非你被迫使用古老的Java版本(1.5之前,Sun甚至不再支持),否则你应该使用Java的real Enums,这可以为你节省大量的工作和麻烦(因为旧版本)风格的类型安全的枚举很难得到正确的,并且只是一切都很棒。

答案 3 :(得分:1)

初始化SWITZERLAND静态字段的'Country'构造函数调用在countries列表初始化之前发生。如果更改静态字段定义的顺序,它将更好。

答案 4 :(得分:-1)

我认为下面的代码可能有效。类的构造函数必须定义为非私有的公共方法。

国家(字符串constname){
             //当前未使用constname(我将其用于Map中的Key)             的System.out.println(constname);             System.out.println(“Ref debug:”+ this);

        //Ad this to the Countries
        Country.countries.add(this);
    }