Pull to refresh

Интересная работа сборщика мусора

Reading time3 min
Views2.2K
Проблема
Явой занялся я недавно, и столкнулся с интересной проблемой связанной с динамическим переопределением методов во время исполнения. После выхода из переопределенного метода терялась ссылка на объект. Решение проблемы затянулось в связи с тем, что на одном компьютере она была, а на другом нет.


Структура кода
У меня есть класс Резидент.

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().

ПС. Я могу быть не прав в определении причины сего. Буду рад услыщать мнения
Tags:
Hubs:
+3
Comments25

Articles

Change theme settings