首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中的内存问题/错误

Java中的内存问题/错误
EN

Stack Overflow用户
提问于 2016-01-20 00:51:09
回答 2查看 85关注 0票数 1

下面是我在用Java制作的冒险游戏中的一个方法:

代码语言:javascript
复制
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]);
        }
    }

}

我遇到的问题是,在第一个双"for“循环中,打印的每个字符都是具有各种不同属性的不同字符。但是,当第二个double "for“循环运行并打印出我刚刚创建的所有字符时,它会打印出所有相同的字符,如下所示:

代码语言:javascript
复制
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

我认为这是某种内存问题,我将mapa (一个location对象)中的字符设置为charTesta中的字符。charTest在前面的代码中已经被实例化了。

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

Location.java:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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;
}
}
EN

回答 2

Stack Overflow用户

发布于 2016-01-20 01:02:12

在这一行中,必须将末尾的inv更改为new Item[1]

代码语言:javascript
复制
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); 

因此,下面这行代码可以完成这项工作:

代码语言:javascript
复制
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赋给另一个变量,则可以复制 reference

这意味着在您的示例中,所有Character对象都具有相同的对象。

显然,在您的中存在相同的问题

代码语言:javascript
复制
map[a][b].chars[1]

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

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

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

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2016-01-20 01:25:47

也许你应该试着用任何人,包括你自己,都能理解的方式重写你的代码?如果你的代码看起来像这样,难怪你会迷失其中。

像wRand和inv这样的

  • 变量名并不能告诉我们它们做了什么,
  • 将代码块分成了几个小方法,并给它们起了个好名字
  • ,字符构造函数的调用简直是疯了。如果possible
  • Don't在您的代码中到处使用幻数,
  • 将使用集合而不是数组。
  • 尝试避免缩进级别为3和嵌套循环
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34882467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档