初始化所有变量但仍然出现NullPointerExceptions错误

时间:2014-02-01 23:59:18

标签: java nullpointerexception

以下是代码:

public class Fisher{

    private String name;
    private Fish [] fishCaught;
    private int numFishCaught;
    private int keepSize;
    public static int LIMIT =10;
    private boolean full;

    public int getnumFishCaught(){
        return numFishCaught;
    }
    public Fisher(String n,int k){
        this.name=n;
        this.keepSize=k;
        this.fishCaught =new Fish[LIMIT];

    }
    public String toString(){
        return this.name + " with " + numFishCaught+ " fish ";
    }
    public void keep(Fish f){
        if(numFishCaught<LIMIT){
            this.fishCaught[numFishCaught]=f;
            numFishCaught++;
            full=false;
        }else{
            full=true;
            numFishCaught=LIMIT;
        }

    }
    public boolean likes(Fish f1){
        if(f1.getSpecies().equals("Sunfish")){
            return false;
        }else{
            if(f1.getSize()>=this.keepSize){
                return true;
            }else{
                return false;
            }
        }
    }
    public void listFish(){

        System.out.println( this.name +" with "+ numFishCaught + " fish as follow: ");
        for(int i=0;i<numFishCaught;i++){
            System.out.println("A " + this.fishCaught[i].getSize() +" cm " + this.fishCaught[i].getSpecies());
        }
    }
    public void goFishingIn(Pond p){

        if(likes(p.catchAFish())){ // the problem happens here
            keep(p.catchAFish());
            if(full==true)
                p.add(p.catchAFish());
        }
    }
    public void giveAwayFish(Fisher f1,Pond pp){
        this.keepSize=f1.keepSize;
        for(int i=0;i<numFishCaught;i++){
            if(likes(fishCaught[i])==true){
                f1.keep(fishCaught[i]);
            }else{
                pp.add(fishCaught[i]);
            }
        }
    }
}

另外两个班,鱼和池,是:

public class Pond {

    private Fish [] fish;
    private int numFish;
    private int capacity;
    private boolean full;
    private Fish fff;

    public Pond(int c){

        capacity=c;
        fish= new Fish[capacity];
        fff= new Fish(0,"UNKNOWN");
    }
    public boolean isFull(){

        if(numFish>capacity){
            full=true;
            return true;
        }
        else{
            full=false;
            return false;
        }
    }
    public int getNumFish(){
        return numFish;
    }

    public void add(Fish f){

        if(full==false){
            fish[numFish]=f;
            numFish++;
        } 
    } 
    public void listFish(){

        System.out.println("Pond with " + numFish + " fish as follow: ");
        for(int i=0;i<numFish;i++){
            System.out.println("A " + fish[i].getSize() +" cm " + fish[i].getSpecies());
        }
    }
    public Fish catchAFish(){

        int num= (int)(Math.random() * (numFish-1));
        if(fish[num]!=null && numFish>0){
            fff= fish[num];
            fish[num]= fish[numFish-1];
            fish[numFish-1]=null;
            numFish--;
            return fff;
        }
        else
            return null;
    }
    public String toString(){
        return "Pond with "+  numFish +" "+ fish[numFish];
    }
}

Stacktrace:

java.lang.NullPointerException
    at Fisher.likes(Fisher.java:34)
    at Fisher.goFishingIn(Fisher.java:53)
    at FishingTestProgram2.main(FishingTestProgram2.java:28)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)

有人可以告诉我为什么p.catchAFish()likes(Fish f1)中的类型不同? 因为我认为catchAFish方法将返回一个Fish对象,它与likes方法中的输入类型相同。

public class Fish {
    private String species;
    private int size;
    public String getSpecies(){
        return species;
    }
    public int getSize(){
        return size;
    }
    public Fish(int s, String ss){
        size=s;
        species=ss;
    }
    public String toString(){
        return "A " + size+"cm "+ species;
    }
}

测试类:

public class FishingTestProgram2 { 
    public static void main(String [] args) { 
        // Create a big pond with 15 fish 
        Pond bigPond = new Pond(15); 
        bigPond.add(new Fish(4, "Sunfish")); 
        bigPond.add(new Fish(25, "Pike")); 
        bigPond.add(new Fish(20, "Bass")); 
        bigPond.add(new Fish(30, "Perch")); 
        bigPond.add(new Fish(14, "Sunfish")); 
        bigPond.add(new Fish(15, "Pike")); 
        bigPond.add(new Fish(9, "Pike")); 
        bigPond.add(new Fish(12, "Bass")); 
        bigPond.add(new Fish(5, "Sunfish")); 
        bigPond.add(new Fish(12, "Sunfish")); 
        bigPond.add(new Fish(10, "Bass")); 
        bigPond.add(new Fish(2, "Bass")); 
        bigPond.add(new Fish(16, "Perch")); 
        bigPond.add(new Fish(30, "Sunfish")); 
        bigPond.add(new Fish(7, "Perch")); 
        bigPond.listFish(); 

        // Create two people to fish in the pond 
        Fisher fred = new Fisher("Fred", 15); 
        Fisher suzy = new Fisher("Suzy", 10); 

        System.out.println("First Fred catches 20 fish in the big pond ..."); 
        for (int i=0; i<20; i++) 
            fred.goFishingIn(bigPond); 
        fred.listFish(); 

        System.out.println("Suzy now catches 20 fish in the big pond ..."); 
        for (int i=0; i<20; i++) 
            suzy.goFishingIn(bigPond); 
        suzy.listFish(); 

        System.out.println("Here is what is left of the pond ..."); 
        bigPond.listFish();
        // Now simulate Suzy giving her fish to Fred 
        suzy.giveAwayFish(fred, bigPond); 
        fred.listFish(); 
        suzy.listFish(); 
        bigPond.listFish();  
    } 
} 

字符串比较行是正确的我在我试图解决问题时更改了它。  调试说明了这一点。指鱼和p。 means(int,string)我需要在同一类型中初始化这两个东西,但我不知道如何更改它。

1 个答案:

答案 0 :(得分:2)

catchAFish()返回null,因此当您传递likes()时,if(f1.getSpecies()=="Sunfish")在调用if(likes(p.catchAFish())){ // the problem happens here时会在相似内容中获得空引用。

我不知道如何调用goFishingIn(),你不提供该代码。但是你最有可能用一个悲伤的空池来称呼它。

您需要在使用catchAFish的返回值之前检查null,或者确保catchAFish永远不会返回null。现在它会。

好的 - 我看到了你的主要功能。问题是你出去钓鱼了。

  public Fish catchAFish(){

    int num= (int)(Math.random() * (numFish-1));
    if(fish[num]!=null && numFish>0){
      fff= fish[num];
      fish[num]= fish[numFish-1];
      fish[numFish-1]=null;
      numFish--;
      return fff;
    }
    else
      return null;
  }

你将你的数组初始化为20,但是每次钓鱼你都会删除整个Fish类,所以当你打电话给goFishingIn时,你要从池塘中的鱼群中移除一个Fish对象。

我想你想要去掉一条鱼,一旦鱼类全部被捕获[num] == 0,那就去除鱼。

  public Fish catchAFish(){

    int num= (int)(Math.random() * (numFish-1));
    if(fish[num]!=null && numFish>0){
      fff= fish[num];
      fish[num]--;
      if (fish[num] == 0)
      { 
          // No more of this fish type, remove it from the pond.
          fish[num]= fish[numFish-1];
          fish[numFish-1]=null;
          numFish--;
      }
      return fff;
    }
    else
      return null;
  }