Удаление объекта URLConnection из ArrayList<URLConnection>

В моей программе мне нужно отслеживать список открытых подключений к какому-либо 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/", то "Результат удаления = ложь".

Я не понимаю такого поведения. У меня есть некоторые предположения, но я не уверен...

Кто-нибудь может помочь?

1 ответ

Решение

Короче говоря (по крайней мере, с HotSpot JVM 23.7-b01) мы имеем это conn.equals(conn)==false когда схема URL HTTPS.

Операция remove(Object o) определяется как удаление элемента е так, что (o==null ? e==null : o.equals(e)) (т.е. удалить определяется с точки зрения равных). Можно ожидать, что remove (conn) будет успешным, так как элемент был только что вставлен, но так как conn.equals(conn) является false, реализация коллекции понимает, что элемент не содержится.

Это странный случай, когда равные не рефлексивны. Из реализации openjdk причина ясна: HttpsURLConnectionImpl делегирует реализацию equals внутреннему объекту, который не равен оболочке.

public class HttpsURLConnectionImpl {
   protected DelegateHttpsURLConnection delegate;
   public boolean equals(Object obj) {
    return delegate.equals(obj);
   }
}
Другие вопросы по тегам