代码之家  ›  专栏  ›  技术社区  ›  Polta Lashka

抛出Java的InnerClass的Java数组。lang.NoSuchFieldError语言

  •  -2
  • Polta Lashka  · 技术社区  · 7 年前

    很长一段时间后,我正在努力温习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 + '}';
    }
    

    }
    }

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

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

    怎样才能使这个(或类似的想法)奏效呢。 谢谢

    2 回复  |  直到 7 年前
        1
  •  1
  •   Ari Singh    7 年前

    您需要使用新器官初始化vitalOrgrans()。例如:

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

    因为当你说:

    Organs[] vitalOrgans = new Organs[3];
    

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

        2
  •  1
  •   Brandon McKenzie    7 年前

    获取代码的相关位:

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

    自你宣布 vitalOrgans 从未给过访问修饰符(即 private , public , protected )它采用默认访问权限,这意味着只有同一个包中的其他类才能看到它。由于您的另一个代码块不在同一个包中,因此它无法看到该字段。

    一个最简单可行的修改就是将访问权限设置为 平民的 :

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

    虽然这是可行的,但它不一定是最好的解决方案,因为如果您改变了vitalOrgans的表示方式,或者需要执行任何验证,那么这些编辑必须在整个应用程序中进行。因此,一个更好的解决方案(也是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方法访问器官(注意,您可能希望器官是公共的):

    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!