在创建自定义子类的实例时获取NullReference

时间:2016-09-05 18:44:05

标签: java arrays inheritance

首先,感谢您花时间阅读!

所以,我创建了一个名为Phone的超类,并制作了三个子类LG,三星和华为。我试图做这个MVC风格,所以我去控制器包测试我的代码,导入所有创建的类,所以我可以通过输入一个String来实例化它们,这将指定要创建的子类(使用开关执行此操作)。 运行程序并正确输入名称后,我得到了一个N​​ullReference。我打开调试,发现'p',用于循环的变量,从未实例化过。

怎么来的?非常感谢任何帮助!

public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    Phone[] phones = new Phone[3];
    for(Phone p : phones){
        System.out.println("What brand?");
        String inputBrand = scan.nextLine();
        switch(inputBrand) {
        case "LG" : p = new LG();
            break;
        case "Samsung" : p = new Samsung();
            break;
        case "Huawei" : p = new Huawei();
            break;
        default : System.out.println("You're an idiot");
            break;
        }
    }
    for(Phone p : phones){
        System.out.println(p.toString());
    }
    scan.close();
}

2 个答案:

答案 0 :(得分:0)

该行实例化数组,但不实例化其内容:

Phone[] phones = new Phone[3];

您正在使用的Foreach基于迭代器,它根据您的预期检查数组的内容,而不是其大小。

p = new LG()

这一行将新的LG()分配给一个临时变量,该变量在循环内部,而不是手机[i],如你的意图所示。

我建议使用List来存储你的对象:

private static final int LOOPS = 3;

public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    List<Phone> phones = new ArrayList<>();
    for(int i = 0; i < LOOPS; i++){
        System.out.println("What brand?");
        String inputBrand = scan.nextLine();
        switch(inputBrand) {
            case "LG" : phones.add(new LG());
                break;
            case "Samsung" : phones.add(new Samsung());
                break;
            case "Huawei" :  phones.add(new Huawei());
                break;
            default : System.out.println("Your code is less than optimal");
                break;
        }
    }
    for(Phone p : phones){
        System.out.println(p.toString());
    }
    scan.close();
}

答案 1 :(得分:0)

你应该这样做:

    for (int i = 0; i < phones.length; i++) {

        System.out.println("What brand?");
        String inputBrand = scan.nextLine();
        switch (inputBrand) {
        case "LG":
        phones[i] = new LG();
        break;
        etc etc

因为您可以访问数组的元素,在另一种情况下,您正在设置手机的副本,在声明时保持数组完好无损... 因此,NPE