Java中的内存问题/错误

时间:2016-01-19 16:51:09

标签: java

以下是我用Java制作的冒险游戏中的方法:

public static void characterDisperse(){

    int wRand = (int)(Math.random())*wModifiers.length;
    Item[] inv = new Item[1];
    inv[0]=new Item(wModifiers[wRand] + " " + wNames[(int)(Math.random()*wNames.length)],(int)(Math.random()*wModifiers.length)*2,1);
    for(int a=0;a<10;a++){
        for(int b=0;b<10;b++){
            if(Math.random()>0.5){ //density of characters
                charTest[a][b] = new Character(names[(int)(Math.random()*names.length)],(int)(Math.random()*5),(int)(Math.random()*3),(int)(Math.random()*15+5)*10,2,inv); 

                map[a][b].chars[1] = charTest[a][b];
                System.out.println(map[a][b].chars[1]);

            }
            else{
                map[a][b].passable = false;
            }


        }
    }
    for(int d=0;d<10;d++){
        for(int e=0;e<10;e++){
            System.out.println(map[d][e].chars[1]);
        }
    }

}

我遇到的问题是,在第一个双重&#34; for&#34;循环,打印的每个字符都是不同的字符,具有各种不同的属性。然而,当第二个双&#34;为&#34;循环运行并打印出我刚刚创建的所有字符,它打印出所有相同的字符,见下文:

NAME: Moriah    RACE: 4 ALIGNMENT: 0    HEALTH: 130 SKILL: 2    INVENTORY: 1
NAME: Marge RACE: 1 ALIGNMENT: 0    HEALTH: 160 SKILL: 2    INVENTORY: 1
NAME: Faith RACE: 0 ALIGNMENT: 1    HEALTH: 50  SKILL: 2    INVENTORY: 1
NAME: Morton    RACE: 3 ALIGNMENT: 2    HEALTH: 60  SKILL: 2    INVENTORY: 1
NAME: Sherwood  RACE: 1 ALIGNMENT: 2    HEALTH: 50  SKILL: 2    INVENTORY: 1
NAME: Ezequiel  RACE: 2 ALIGNMENT: 1    HEALTH: 150 SKILL: 2    INVENTORY: 1
NAME: Herschel  RACE: 2 ALIGNMENT: 2    HEALTH: 70  SKILL: 2    INVENTORY: 1
NAME: Lester    RACE: 3 ALIGNMENT: 2    HEALTH: 80  SKILL: 2    INVENTORY: 1
NAME: Corinna   RACE: 2 ALIGNMENT: 0    HEALTH: 190 SKILL: 2    INVENTORY: 1

FIRST FOR LOOP ENDS HERE
SECOND FOR LOOP BEGINS

NAME: Corinna   RACE: 2 ALIGNMENT: 0    HEALTH: 190 SKILL: 2    INVENTORY: 1
NAME: Corinna   RACE: 2 ALIGNMENT: 0    HEALTH: 190 SKILL: 2    INVENTORY: 1
NAME: Corinna   RACE: 2 ALIGNMENT: 0    HEALTH: 190 SKILL: 2    INVENTORY: 1
NAME: Corinna   RACE: 2 ALIGNMENT: 0    HEALTH: 190 SKILL: 2    INVENTORY: 1
NAME: Corinna   RACE: 2 ALIGNMENT: 0    HEALTH: 190 SKILL: 2    INVENTORY: 1
NAME: Corinna   RACE: 2 ALIGNMENT: 0    HEALTH: 190 SKILL: 2    INVENTORY: 1
NAME: Corinna   RACE: 2 ALIGNMENT: 0    HEALTH: 190 SKILL: 2    INVENTORY: 1
NAME: Corinna   RACE: 2 ALIGNMENT: 0    HEALTH: 190 SKILL: 2    INVENTORY: 1

我认为这是某种内存问题,我将map [a] [b](位置对象)中的字符设置为charTest [a] [b]中的字符。 charTest早已在代码中实例化了。

map [] []是一个10x10的Location对象数组,charTest [] []是一个10x10的Character对象数组:

Location.java:

import java.awt.*;
public class Location{

Character[] chars;
Feature[] features;
boolean passable;

public Location(Character[] chars, Feature[] features, boolean passable){
    this.chars = chars;
    this.features = features;
    this.passable = passable;
}

public String toString(){
    return "test";
}

public boolean containsChars(Location l){
    if(l.chars.length>0){
        return true;
    }
    else{
        return false;
    }
}

}

Character.java:

public class Character{
String name;  
int race;
int alignment;

int health;

int skill;

Item[] inventory;

public Character(String name,int race,int alignment,int health,int skill,Item[] inventory){
    this.name = name;
    this.race = race;
    this.alignment = alignment;
    this.health = health;
    this.skill = skill;
    this.inventory = inventory;
}


public String toString(){
    String printOut = "NAME: " + name + "\tRACE: " + race + "\tALIGNMENT: " + alignment + "\tHEALTH: " + health + "\tSKILL: " + skill + "\tINVENTORY: " + "1";
    return printOut;
}
}

2 个答案:

答案 0 :(得分:1)

在此行中,您必须将inv最后更改为new Item[1]

charTest[a][b] = new Character(names[(int)(Math.random()*names.length)],(int)(Math.random()*5),(int)(Math.random()*3),(int)(Math.random()*15+5)*10,2,inv); 

所以这一行可以胜任:

charTest[a][b] = new Character(names[(int)(Math.random()*names.length)],(int)(Math.random()*5),(int)(Math.random()*3),(int)(Math.random()*15+5)*10,2,new Item[1]);

原因是,当您使用此Item[] inv = new Item[1];创建数组时,此数组的引用将分配给变量inv。然后,如果您将值inv分配给另一个变量复制 参考

这意味着在您的情况下,所有Character个对象都具有相同的对象。

你的

中显然有同样的问题
map[a][b].chars[1]

创建map[a][b]时,您将同一个chars数组分配给map中的所有字段。

然后,每次创建新的Character时,都会将他放入相同的chars数组中,该数组将替换旧的并打印出来。这就是为什么你在生成它们时看到新角色的原因,这就是为什么最后一个角色在所有map变量中都是相同的。

为map生成初始数据时,必须为每个Location创建新数组,如下所示:

for(int a=0;a<10;a++){
        for(int b=0;b<10;b++){
            map[a][b] = new Location(new Character[5], new Feature[5], true);
        }
}

PS:我强烈建议使用ArrayLists而不是数组。

答案 1 :(得分:-1)

也许你应该尝试以任何人(包括你自己)都能理解它的方式重写你的代码?如果你的代码看起来像这样,那么你就会迷失它。

  • wRand和inv之类的变量名不会告诉他们做什么
  • 以小方法拆分Code-Blob并给它们一个好名字
  • Character Constructor调用是疯了。重构它并可能应用工厂模式
  • 创建单个函数,执行一项操作,例如随机化Race,Name,Health等。
  • 尽可能使用集合代替数组
  • 不要在代码中使用魔术数字。
  • 尽量避免缩进级别为3和嵌套循环