Проблема
Явой занялся я недавно, и столкнулся с интересной проблемой связанной с динамическим переопределением методов во время исполнения. После выхода из переопределенного метода терялась ссылка на объект. Решение проблемы затянулось в связи с тем, что на одном компьютере она была, а на другом нет.
Структура кода
У меня есть класс Резидент.
От класса Резидент наследуется Бот. И переопределяется метод Турн.
В классе Ворлд имеем массив резидентов.
Полсле выхода из residents[i][j].Turn(), residents[i][j] полчался равен null. И дальше все вылеталало по исключению. Как я и говорил на некоторых компах проблема была, а на некоторых нет.
Почему
Потому что Бот объявлен в классе Програм. И при входе в Турн метод бота ссылка на него теряется и уже на выходе сборщик мусора объект удаляет. Решается проблема либо так:
* This source code was highlighted with Source Code Highlighter.
Либо созданием бота в Ворлде через метод w.AddBot().
ПС. Я могу быть не прав в определении причины сего. Буду рад услыщать мнения
Явой занялся я недавно, и столкнулся с интересной проблемой связанной с динамическим переопределением методов во время исполнения. После выхода из переопределенного метода терялась ссылка на объект. Решение проблемы затянулось в связи с тем, что на одном компьютере она была, а на другом нет.
Структура кода
У меня есть класс Резидент.
public class Resident {
/*Variables*/
int age;
String trace;
boolean live;
int energy;
String name;
int id;
int x;
int y;
World world;
/*Body*/
public void Turn() {
age++;
}
}
От класса Резидент наследуется Бот. И переопределяется метод Турн.
public class Bot extends Resident {
/*Variables*/
Queue m;
Vector moves = new Vector();
/*Constrctors*/
public Bot(int energy, String name, World world) {
this.energy = energy;
this.name = name;
this.trace = "";
if (this.energy < 1) {
this.live = false;
} else {
live = true;
}
this.world = world;
this.age = 0;
}
/*Body*/
public void Turn() {
age++;
energy--;
if (!moves.isEmpty()) {
world.ResidentAction(this, (ACTION) moves.lastElement());
moves.remove(moves.size() — 1);
}
}
}
В классе Ворлд имеем массив резидентов.
public class World {
/*Variables*/
String name;
int width;
int height;
Resident[][] residents;
/*Constrctors*/
public World(String name, int height, int width) {
this.height = height;
this.name = name;
this.width = width;
this.residents = new Resident[height][width];
}
/*Body*/
public void AddBot() {
Bot b = new Bot(100, "B", this);
residents[1][2] = b;
b.X(1);
b.Y(2);
}
public void AddBot(Bot b) {
residents[1][2] = b;
b.X(1);
b.Y(2);
}
public void AddBot(Bot b, int x, int y) {
residents[x][y] = b;
b.X(x);
b.Y(y);
}
public void Turn() {
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
if (residents[i][j] != null) {
residents[i][j].Turn();
if (!residents[i][j].isLive())
residents[i][j] = null;
}
}
}
}
}
В Мейне. Создаем объект типа Ворлд и Бот, и запихиваем Бота в Ворлд по координатам 1,2. Потом пробуем выполнить метод Турн для ворлда.
public class Programm {
public static void main(String[] args) {
World w = new World("Test1", 100, 100);
Bot b = new Bote(20, "B", w)
w.AddBot(b);
w.Turn();
}
}
* This source code was highlighted with Source Code Highlighter.
Полсле выхода из residents[i][j].Turn(), residents[i][j] полчался равен null. И дальше все вылеталало по исключению. Как я и говорил на некоторых компах проблема была, а на некоторых нет.
Почему
Потому что Бот объявлен в классе Програм. И при входе в Турн метод бота ссылка на него теряется и уже на выходе сборщик мусора объект удаляет. Решается проблема либо так:
public class Programm {
static Bot b;
public static void main(String[] args) {
World w = new World(«Test1», 100, 100);
b = new Bot(20, "", w);
w.AddBot(b);
w.Turn();
}
}
* This source code was highlighted with Source Code Highlighter.
Либо созданием бота в Ворлде через метод w.AddBot().
ПС. Я могу быть не прав в определении причины сего. Буду рад услыщать мнения