如果我有一个名为“sock”的套接字变量,并且由于某种原因,您必须创建一个新的套接字,假设它称为“sock2”,并且您将“sock2”设置为“sock”。然后你扔掉变量'sock'。连接是否仍然有效,“sock2”是否仍然能够与最初位于“sock”中的套接字的另一端通信?
2 回答
由于仍然存在对原始对象的引用sock
(以 的形式sock2
),Java 垃圾收集不会将其处理掉,您仍然可以sock2
像使用sock
.
基本上你在描述这样的事情
public void test (...) {
Socket sock2;
{
Socket sock = // open socket
sock2 = sock;
// now 'sock' does out of scope; i.e. you "throw it away"
}
// use 'sock2'
}
是的,它会工作得很好。sock
和都是sock2
引用变量(Java 中所有非原始类型的变量也是如此!)。分配sock2 = sock;
只是分配一个引用......所以sock2
现在指向相同Socket
的,sock
您可以使用它与您最初通过 交谈的远程主机交谈sock
。
好的,那么sock2
之前指向 s different Socket
的情况呢。
public void test (...) {
Socket sock2 = // open socket to A
{
Socket sock = // open socket to B
sock2 = sock;
// now 'sock' does out of scope; i.e. you "throw it away"
}
// use 'sock2'
}
它仍然像以前一样工作。出于同样的原因。
唯一需要注意的是,您已经删除了对连接到 A 的套接字的引用。如果您不再拥有对A
套接字的引用,您的应用程序将无法使用它。(这不会影响您与B
... 交谈的能力,因为您仍然有那个参考 ... in sock2
)。
那么现在会发生什么?好吧,我们现在遇到了 JavaSocket
对象A
不再可供代码使用的情况。(用 Java 的说法,对象是“不可访问的”。)这意味着它有资格进行垃圾回收。但这并不意味着它会立即被垃圾收集。事实上,垃圾收集器运行之前可能需要几秒钟……或几天……。同时,可能仍然存在与某些远程主机的开放连接,从而在本地和远程绑定资源。这是资源泄漏,可能会造成严重后果。(当 GC 最终回收套接字时,实现对象的终结器将关闭底层连接并释放任何资源。但损坏可能已经造成。)
解决方案是确保您的代码始终及时创建close()
任何Socket
对象......并且不允许引用只是“掉在地板上”。