内部类的Java数组抛出java.lang.NoSuchFieldError

时间:2018-02-22 15:48:56

标签: java inner-classes

我想在很长一段时间后刷新java。 任何帮助深表感谢。

为了演示我有动物类,它有一个器官的内部数组。

public class Animal 
   {
    String nameOfAnimal;
    Organs [] vitalOrgans = new Organs[3];

    public Animal()
    {
    }

    public String getNameOfAnimal() {
        return nameOfAnimal;
    }

    public void setNameOfAnimal(String nameOfAnimal) {
        this.nameOfAnimal = nameOfAnimal;
    }

    @Override
    public String toString() {
        return "Animal{" + "nameOfAnimal=" + nameOfAnimal + "}";
    }
class Organs{

String nameOfOrgan; 
public String getNameOfOrgan() {
    return nameOfOrgan;
}
public void setNameOfOrgan(String nameOfOrgan) {
    this.nameOfOrgan = nameOfOrgan;
}

@Override
public String toString() {
    return "Organs{" + "nameOfOrgan=" + nameOfOrgan + '}';
}

}
}

现在在驱动程序文件中进行调用时没有语法错误,但我得到“线程中的异常”主“java.lang.NoSuchFieldError:vitalOrgans”

    Animal mamal = new Animal(); 
    mamal.setNameOfAnimal("Chimp");
    mamal.vitalOrgans[0].setNameOfOrgan("Heart");
    System.out.println(mamal.vitalOrgans[0].getNameOfOrgan());

使这个(或类似的想法)起作用的方法是什么。 谢谢。

2 个答案:

答案 0 :(得分:1)

取相关的代码:

public class Animal 
{
    //...
    Organs [] vitalOrgans = new Organs[3];
    //...
}

由于您的vitalOrgans声明从未被授予访问修饰符(即privatepublicprotected之一),因此它采用了默认访问权限,这意味着只有其他权限同一个包中的类可以看到它。由于您的其他代码块不在同一个包中,因此无法看到该字段。

使其成功的最低限度可行的修改是设置对public的访问权限:

public class Animal 
{
    //...
    public Organs [] vitalOrgans = new Organs[3];
    //...
}

虽然这有效,但它不一定是最好的解决方案,就好像你曾经改变了有关器官的代表性,或者需要执行任何验证一样,这些编辑必须在整个应用程序中完成。因此,一个更好的解决方案(以及出于那些确切原因的Java中的主要风格惯例)是使它(以及所有你的领域,实际上)私有并通过方法访问:

public class Animal {
    private String nameOfAnimal;
    private Organs[] vitalOrgans = new Organs[3];

    //...

    public Organs[] getVitalOrgans() {
        return vitalOrgans;
    }

    //Alternative accessor that fetches only one organ.
    public Organs getVitalOrgan(int index) {
        if(index >= 0 && index < vitalOrgans.length)
            return vitalOrgans[index];
        else
            return null;
    }

    public void setVitalOrgans(Organs[] vitalOrgans) {
        this.vitalOrgans = vitalOrgans
    }

    //...
}

然后你的来电者可以通过任何形式的get方法访问Organs(注意,你可能希望Organs公开):

Animal.Organs futureMammalHeart = mamal.getVitalOrgan(0); //Animal.Organs due to Organs being an inner class.
if(futureMammalHeart != null) //Demonstration of null check.  Safety first!
    futureMammalHeart.setNameOfOrgan("Heart");
Animal.Organs[] mammalianVitalOrgans = mamal.getVitalOrgans();
if(mammalianVitalOrgans != null) //Just in case...
    System.out.println(mamal.mammalianVitalOrgans[0].getNameOfOrgan());

另外,正如Ari在他的回答中提到的,不要忘记初始化数组中的器官,否则你会得到一个NullPointerException!

答案 1 :(得分:1)

您需要使用新的Organs()初始化vitalOrgrans。像:

public Animal() {
    for (int i = 0; i < vitalOrgans.length; i++) {
        vitalOrgans[i] = new Organs();
    }
}

因为当你说:

Organs[] vitalOrgans = new Organs[3];

您正在创建一个由3个null器官组成的数组。因此,当访问“vitalOrgans [i]。”时,空指针异常。