2008-11-18 43 views

Trả lời

57

Sau khi xóa loại, tất cả thông tin được biết về T là nó là một số phân lớp của Object. Bạn cần chỉ định một số nhà máy để tạo các phiên bản T.

Một cách tiếp cận có thể sử dụng một Supplier<T>:

class MyClass<T> { 

    private final Supplier<? extends T> ctor; 

    private T field; 

    MyClass(Supplier<? extends T> ctor) { 
    this.ctor = Objects.requireNonNull(ctor); 
    } 

    public void myMethod() { 
    field = ctor.get(); 
    } 

} 

Cách sử dụng có thể trông như thế này:

MyClass<StringBuilder> it = new MyClass<>(StringBuilder::new); 

Ngoài ra, bạn có thể cung cấp một đối tượng Class<T>, và sau đó sử dụng phản ánh.

class MyClass<T> { 

    private final Constructor<? extends T> ctor; 

    private T field; 

    MyClass(Class<? extends T> impl) throws NoSuchMethodException { 
    this.ctor = impl.getConstructor(); 
    } 

    public void myMethod() throws Exception { 
    field = ctor.newInstance(); 
    } 

} 
+0

gói gì 'Supplier' tọa lạc tại? 'MyClass (Lớp impl)' phải khai báo 'ném NoSuchMethodException' để được biên dịch. Câu trả lời của bạn không may là không thân thiện với người mới bắt đầu Java. – user927387

+0

@ user927387 'java.util.function.Supplier' – erickson

10

Điều này có thể nặng hơn những gì bạn đang tìm kiếm, nhưng nó cũng sẽ làm việc. Lưu ý rằng nếu bạn sử dụng cách tiếp cận này, sẽ có ý nghĩa hơn khi đưa nhà máy vào MyClass khi nó được xây dựng thay vì chuyển nó vào phương thức của bạn mỗi khi nó được gọi.

interface MyFactory<T> 
{ 
    T newObject(); 
} 

class MyClass<T> 
{ 
    T field; 
    public void myMethod(MyFactory<T> factory) 
    { 
     field = factory.newObject() 
    } 
} 
+1

Cách tiếp cận tốt, không phản chiếu; phản ánh không phải lúc nào cũng là một lựa chọn. myMethod sẽ có thể chấp nhận MyFactory , phải không? – erickson

+0

Cuộc gọi tốt - bạn sẽ muốn đặt một ký tự đại diện bị chặn vào nhà máy để cho phép các đối tượng kiểu T và các lớp con của T được tạo trong myMethod(). –

11

Một cách tiếp cận khác không phản chiếu là sử dụng mô hình Hybrid Builder/Abstract Factory.

Trong Java hiệu quả, Joshua Bloch đi qua mô hình Builder trong từng chi tiết, và chủ trương một giao diện Builder generic:

public interface Builder<T> { 
    public T build(); 
} 

xây dựng bê tông có thể thực hiện giao diện này, và các lớp bên ngoài có thể sử dụng xây dựng cụ thể để cấu hình Builder theo yêu cầu. Người xây dựng có thể được chuyển đến MyClass dưới dạng Builder<T>.

Sử dụng mẫu này, bạn có thể nhận các phiên bản mới T, ngay cả khi T có thông số hàm tạo hoặc yêu cầu cấu hình bổ sung. Tất nhiên, bạn sẽ cần một số cách để chuyển Builder vào MyClass. Nếu bạn không thể chuyển bất kỳ thứ gì vào MyClass, thì Trình xây dựng và Nhà máy Tóm tắt sẽ hết.

1

Lớp classOfT

 try { 
      t = classOfT.newInstance();//new T(); NOTE: type parameter T cannot be instantiated directly 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
Các vấn đề liên quan