2013-02-26 41 views
7

Trong chương trình của tôi, tôi cần theo dõi danh sách các kết nối đã mở tới một số máy chủ HTTP - để ngắt kết nối chúng cùng một lúc nếu cần.Xóa đối tượng URLConnection khỏi ArrayList <URLConnection>

Tôi gặp sự cố sau. Nếu tôi kết nối với máy chủ HTTP, mọi thứ hoạt động hoàn hảo, nhưng nếu để HTTPS, thì các kết nối sẽ không bị xóa khỏi danh sách. Nó dẫn đến rò rỉ bộ nhớ.

Ví dụ:

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); 
     } 
    } 
} 

Nếu điểm URL để "http://www.example.com", sau đó "Kết quả của việc loại bỏ = true".

Nhưng nếu URL trỏ đến "https://www.example.com" thì "Kết quả xóa = false".

Tôi không hiểu hành vi như vậy. Tôi có một số giả định, nhưng không chắc chắn ...

Ai cũng có thể giúp bạn?

Trả lời

6

Tóm lại (ít nhất, với HotSpot JVM 23.7-b01), chúng tôi có conn.equals(conn)==false khi lược đồ URL là HTTPS.

Các hoạt động remove(Object o)defined như loại bỏ một yếu tố e(o==null ? e==null : o.equals(e)) (ví dụ: loại bỏ được định nghĩa về bằng). Người ta có thể mong đợi rằng remove (conn) thành công, vì phần tử vừa được chèn vào, nhưng từ conn.equals(conn)false, việc triển khai bộ sưu tập hiểu rằng phần tử không được chứa.

Đây là trường hợp lạ khi bằng không phản ánh. Từ the openjdk implementation lý do rõ ràng: HttpsURLConnectionImpl ủy quyền việc triển khai bằng đối tượng bên trong, là không bằng cho trình bao bọc.

public class HttpsURLConnectionImpl { 
    protected DelegateHttpsURLConnection delegate; 
    public boolean equals(Object obj) { 
    return delegate.equals(obj); 
    } 
} 
+0

Vì vậy, nó thực sự là trường hợp của hành vi lạ của _equals _... Tôi đã gửi đi lời giải thích như vậy bởi vì nó thực sự là điên ... Cảm ơn! BTW, bạn không biết bất kỳ ví dụ khác của các lớp học với hành vi _equals_ như vậy? –

+0

Không, thực sự tôi cũng không biết điều này. Trường hợp duy nhất của việc triển khai lỗi * bằng * mà tôi có thể gọi lại là của java.net.URL (trong trường hợp này lỗ hổng là về sự nhất quán: quan hệ bình đẳng phụ thuộc vào độ phân giải DNS, do đó hai trường hợp URL có thể hoặc không bằng nhau tùy thuộc vào địa chỉ IP được giải quyết, nhưng đó là một câu chuyện khác). – Javier

+0

Bây giờ mọi thứ đều rõ ràng. Cảm ơn! –

Các vấn đề liên quan