2009-08-19 32 views
9

Lợi ích của việc xây dựng chung cho một lớp không chung chung là gì? Thông số Java cho phép những điều sau đây:Lợi ích của các nhà xây dựng chung

class NonGeneric { 
    <T> NonGeneric() { } 
    ... 
    NonGeneric ref = new <String> NonGeneric(); 
} 

Có thể đưa ra ví dụ thực tế khi tăng cường an toàn cho lớp học không? Làm thế nào nó sẽ tốt hơn so với việc sử dụng Generic ở nơi đầu tiên.

Tôi hiểu rằng các nhà thiết kế Java muốn các nhà thầu phải nhất quán hơn với các phương pháp. Cho rằng nhà xây dựng có thể có tác dụng phụ, nhà thầu chung có thể sử dụng Generics để đột biến một số thông số mà tài liệu tham khảo không được giữ lại, như trong

<T> NonGeneric(T obj, List<T> list) { 
    list.add(obj); 
    // Don't hold a reference to list 
} 

Trả lời

4

Việc sử dụng duy nhất mà tôi có thể nghĩ đến sẽ là nếu các nhà xây dựng cần thiết để sử dụng một đối tượng chung trong khi nó đang chạy, nhưng không lưu trữ đối tượng đó khi nó đã hoàn tất.

Ví dụ:

<T> NonGeneric(T[] blank, List<T> list) { 
    // Sort that list 
    T[] array = list.toArray(blank); 
    Arrays.sort(array); 

    // Pull out the values as strings 
    this.list = new ArrayList<String>(array.length); 
    for (T value : array) { 
     this.list.add(value.toString()); 
    } 
} 

chỉ Nó rất có thể là cái gì mà các nhà thiết kế ngôn ngữ quyết định thực hiện chỉ trong trường hợp ai đó muốn nó, vì không có lý do gì để ngăn chặn những người làm việc đó.

+0

Vâng, nó cho phép các phương thức chung được thay thế bởi các nhà xây dựng (nhưng tại sao bạn muốn?). Tôi đã không bao giờ thực sự nhìn thấy một trong tự nhiên. Đối với tiền của tôi, đó là một biến chứng mà ngôn ngữ có thể đã làm mà không có (như C# đã làm sau này khi nó giới thiệu phiên bản của nó về Generics Java). –

0

Vâng tôi đã nghĩ về cùng một vài lần.

Giả thuyết (có xx lý do tại sao nó không phải như thế này) nó sẽ được tốt đẹp nếu Generic constructors có thể xác định loại chính thức chung cho cả lớp (như khai báo lớp chung), có nghĩa là, nếu xác định constructor chung sẽ cho phép bạn có các trường chung trong lớp đó ...

Ví dụ nếu bạn muốn tránh sự tổng quát:

EntityRequestCallback extends RequestCallback 

nhưng bạn muốn RequestCallback là generic RequestCallback<E extends Entity>, bạn không thể làm điều đó vì chỉ có hai loại yêu cầu thực thể sử dụng PUT/POST. Chỉ các hàm tạo cho các yêu cầu PUT/POST chứa tham số Entity.

public class RequestCallback { 

     /** GET/DELETE requests */ 
    public RequestCallback(String gttUrl, HttpMethod method,) { 
     this.gttUrl = gttUrl; 
       this.method = method; 
    } 

     /** PUT/POST requests */ 
    public RequestCallback(String gttUrl, HttpMethod method, Entity entity) { 
     this.gttUrl = gttUrl; 
       this.method = method; 
     this.entity = entity; 
    } 
} 

Nhưng lớp không thể chung chung bởi vì bạn sẽ được tạo RequestCallback cho một yêu cầu mà không có một thực thể, trong đó sẽ có nghĩa là bạn sẽ nhanh chóng

new RequestCallback(); //without specifying generic parameter - worse than nothing 

Vì vậy, đó là cách duy nhất có thể ở đây là sự tổng quát:

EntityRequestCallback<E extends Entry> extends RequestCallback 

Vì vậy mà bạn có thể có các trường generic:

public E entity; 

Trong ví dụ cụ thể này, việc khái quát hóa là sự lựa chọn đúng, nhưng có những trường hợp tổng quát hóa sẽ không được.

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