如何通过在数组中只引用它来使对象为null?

时间:2016-07-25 14:27:33

标签: java arrays object reference null

我在GameWorld中有一系列游戏对象,他们可以从那个世界中删除。问题是某些游戏对象引用了其他游戏对象。例如。 Player类引用了Bird。 Bird会从GameWorld中随机删除,但Player仍然会引用它。我目前进行空检查以检查GameObject是否仍然有效并且在世界上。但是,从数组中删除对象不会使该引用为null。那我怎么能把它变成空?

以下是一个例子:

// GameWorld creates bird
ArrayList<Object> gameObjects = new ArrayList<>();
Object bird = new Object();
gameObjects.add(bird);

// Player references it
Object referencedBird = gameObjects.get(0);

// later in GameWorld, another scope, there is no access to the 'bird' object, trying to remove the bird from the world
Object objectToRemove = gameObjects.get(0);
gameObjects.remove(0);
objectToRemove = null;

// back in the Player class
Debug.log("is null " + (referencedBird == null)); // false! I need it to be true

4 个答案:

答案 0 :(得分:6)

您无法制作对象 null,您只能制作参考null。更新对象的一个​​引用不会更改对同一对象的其他引用。

想想我们在手机中拥有相同人物的号码:如果我删除号码,则不会从手机中删除。如果我们都删除它,那个人的电话号码就不会存在:我们俩都不能打电话给他们。

你唯一能做的就是:

  • 明确设置referencedBird = null;
  • 或者通过gameObjects.get(0)而不是通过referencedBird变量来引用它。

答案 1 :(得分:1)

好的,因为安迪指出你不能破坏一个物体,你仍然可以解决这个问题。

 interface RemoveAble<T>{
        boolean isRemoved();
        T prepareRemoveAndGet();
    }

class Bird implements RemoveAble<Bird>{
    boolean shouldRemove = false;
    @Override
    public boolean isRemoved() {
        return shouldRemove;
    }

    @Override
    public Bird prepareRemoveAndGet() {
        shouldRemove = true;
        return this;
    }
}

并像这样使用它:

// GameWorld creates bird
ArrayList<RemoveAble> gameObjects = new ArrayList<>();
Bird bird = new Bird();
gameObjects.add(bird);

// Player references it
Bird referencedBird = gameObjects.get(0);

// later in GameWorld, another scope, there is no access to the 'bird' object, trying to remove the bird from the world
Object objectToRemove = gameObjects.get(0).prepareRemoveAndGet;


// back in the Player class
Debug.log("is null " + (referencedBird.isRemoved == true)); // false! I need it to be true

然后自己null e.g。

if(referencedBird.isRemoved) referencedBird = null;

答案 2 :(得分:0)

首先,您需要更好地了解Java变量的工作原理:
我将变量设置为null,这根本不会影响它背后的对象。您需要以某种方式使引用的对象无效(使用布尔变量),或者更好的解决方案是始终直接从ArrayList获取对象。

答案 3 :(得分:0)

与java中的C和C ++不同,你不能直接操作内存,唯一的选择就是删除对obj的所有强(常规)引用,并留给JVM,以便在需要内存时将其从内存中删除。

    // GameWorld creates bird
    ArrayList<Object> gameObjects = new ArrayList<>();
    Object bird = new Object();
    gameObjects.add(bird);

    // a weak reference to array Item
    WeakReference<Object> referencedBird = new    WeakReference(gameObjects.get(0));
    // manipulating and accessing array item via weak reference
    referencedBird.get().toString();

    // after this remove there is no strong reference to array element (0) and it is available for JVM to revoke
    //memory allocated to it in up-coming garbage collection cycle
    gameObjects.remove(0);

    //garbage collection may remove the obj from memory so this method may return null
    referencedBird.get();

此外,您还可以通过制作类型为WeakReference的数组来制作游戏对象列表,提高内存效率

     ArrayList<WeakReference> weakReferenceToGameObjects = new ArrayList<>();
    Object bird1 = new Object();
    weakReferenceToGameObjects.add((WeakReference) bird1);

    bird1 = null;

    // now if you try to get the element you may get null!
    weakReferenceToGameObjects.get(0).get();