考慮下面的Java代碼這些物體是否會被GC收集?
public class PlayerView implements IPlayerListener
{
public Player player;
public PlayerView()
{
player = new Player();
player.listener = this;
}
public void onPlayerEvent()
{
}
}
public class Player
{
public IPlayerListener listener;
public void foo()
{
//do something then
if(this.listener != null)
{
this.listener.onPlayerEvent();
}
}
}
public interface IPlayerListener
{
public void onPlayerEvent();
}
在這裏,我有一個PlayerView和播放器。玩家需要向PlayerView報告事件,所以我創建了一個名爲IPlayerListener的接口,該接口可以爲PlayerListener對象提供一個引用來報告事件。
(我知道在Java中,這不是創建活動的最佳方式,但我並不真的需要「許多聽衆」使用默認「的addEventListener」模式)
問題1:當PlayerView object設置爲null,PlayerView和Player對象是否都會被GC收集?
如果是,那麼請繼續下面的代碼
public class PlayerView implements IPlayerListener, IPlaylistListener
{
public Player player;
public PlayerView()
{
player = new Player();
player.listener = this;
player.playlist = new Playlist();
player.playlist.listener = this;
}
public void onPlayerEvent()
{
}
public void onPlaylistEvent()
{
}
}
public class Player
{
public Playlist playlist;
public IPlayerListener listener;
public void foo()
{
//do something then
if(this.listener != null)
{
this.listener.onPlayerEvent();
}
}
}
public class Playlist
{
public IPlaylistListener listener;
public void bar()
{
//do something then
if(this.listener != null)
{
this.listener.onPlaylistEvent();
}
}
}
public interface IPlayerListener
{
public void onPlayerEvent();
}
public interface IPlaylistListener
{
public void onPlaylistEvent();
}
在這裏,我增加了第三級,Playlist類,其播放器也有一個播放列表對象的引用。 另外播放列表應該有一個監聽器/觀察者。在這種情況下,PlayerView也是播放列表監聽器。
問題2:當PlayerView對象設置爲null時,這些對象是否會被GC收集?
如果答案#2是NO,那麼請繼續
public class PlayerView implements IPlayerListener, IPlaylistListener
{
public Player player;
public PlayerView()
{
player = new Player();
player.listener = this;
player.playlist = new Playlist();
player.playlist.parentPlayer = player;
}
public void onPlayerEvent()
{
}
public void onPlaylistEvent()
{
}
}
public class Player
{
public Playlist playlist;
public IPlayerListener listener;
public void foo()
{
//do something then
if(this.listener != null)
{
this.listener.onPlayerEvent();
}
}
}
public class Playlist
{
public Player parentPlayer;
public void bar()
{
//do something then
if(this.parentPlayer != null)
{
if(this.parentPlayer.listener != null)
{
if(this.parentPlayer.listener instanceof IPlaylistListener)
{
((IPlaylistListener) this.parentPlayer.listener).onPlaylistEvent();
}
}
}
}
}
public interface IPlayerListener
{
public void onPlayerEvent();
}
public interface IPlaylistListener
{
public void onPlaylistEvent();
}
在這裏,我切換與父玩家一個參考playlistListener參考,而不是直接調用playlistListener,檢查如果playerListener也一個PlaylistListener(或兩個接口可以合併爲一個)
問題3:以前的代碼是否能解決問題並收集所有對象?
或者我應該更好地使用第二個代碼塊,並在PlayerView對象中找到合適的時間(就像PlayerView對象從其父視圖中移除之前一樣)並至少調用「player.playlist.listener = null;」。
順便說一句,在播放列表類中,我需要一個對其父Player對象的引用。我應該用WeakReference代替嗎? –