从 ArrayList<URLConnection> 中删除 URLConnection 对象

7
在我的程序中,我需要跟踪打开的连接列表到某个HTTP服务器-以便在需要时立即断开它们。
我遇到了以下问题。如果我连接到HTTP服务器,一切都很完美,但如果连接到HTTPS,则连接不会从列表中删除。这会导致内存泄漏。
例如:
package test;

import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
        try {
            ArrayList<URLConnection> al = new ArrayList<URLConnection>();

            URL url = new URL("http://www.example.com");

            URLConnection conn = url.openConnection();
            al.add(conn);
            System.out.println("Result of removing = " + al.remove(conn));

        } catch (Exception ex) {
            ex.printStackTrace(System.err);
        }
    }
}

如果URL指向“http://www.example.com”,则“删除结果= true”。
但是,如果URL指向“https://www.example.com”,则“删除结果= false”。
我不理解这样的行为。我有一些假设,但不确定...
有人能帮忙吗?
1个回答

6

简而言之(至少在HotSpot JVM 23.7-b01中),当URL方案为HTTPS时,我们有conn.equals(conn)==false

操作remove(Object o)定义为删除一个元素e,使得(o==null ? e==null : o.equals(e))(即用equals定义了删除)。人们可能会期望remove(conn)成功,因为该元素刚刚被插入,但由于conn.equals(conn)false,集合实现会理解该元素不包含在内。

这是一个奇怪的案例,其中equals不是自反的。从openjdk实现中可以清楚地看到原因: HttpsURLConnectionImplequals的实现委托给内部对象,该对象与包装器不相等
public class HttpsURLConnectionImpl {
   protected DelegateHttpsURLConnection delegate;
   public boolean equals(Object obj) {
    return delegate.equals(obj);
   }
}

所以,这确实是_equals_的奇怪行为的情况...我放弃了这样的解释,因为它真的很疯狂...谢谢!顺便问一下,你知道其他具有这种_equals_行为的类的例子吗? - Andrew Orlov
不,我确实也不知道这个。我现在能想起来的唯一一个有缺陷的equals实现是java.net.URL(在这种情况下,缺陷在于一致性:相等关系取决于DNS解析,因此两个URL实例可能相等也可能不相等,但这是另外一个故事)。 - Javier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接