2011-10-15 29 views
6

Bối cảnh: java sử dụng Guice (phiên bản mới)tiêm TypeLiteral với sự phản ánh

Hi tất cả mọi người, là nó có thể tiêm một số TypeLiteral với Guice bằng cách này:

public MyClass<?,?> getMyClass(Injector injector, Class<?> a, Class<?> b) 
{ 
    //how to Inject MyClass with type a & b ? 
    //e.g : injector.getInstance(MyClass<"a class","b class">) 
} 

public interface MyClass<S,T> 
{ 
    public T do(S s); 
} 

public class ClassOne implements MyClass<String,Integer> 
{ 
    public Integer do(String s) 
    { 
      //do something 
    } 
} 

Module : 
bind.(new TypeLiteral<MyClass<String,Integer>(){}).to(ClassOne.class); 
bind.(new TypeLiteral<MyClass<String,Double>(){}).to(ClassTwo.class); 
... 

là gì cách tốt nhất để xử lý vấn đề này (với Guice)?

Cảm ơn bạn!

+1

Duplicate của ysdx

Trả lời

3

Tạo một ParameterizeType cho loại hình của bạn:

// It's supposed to be internal. 
// You could use sun.reflect.generics.reflectiveObjects but it is not portable. 
// Or you can implement it yourself (see below) 
ParameterizedType type = new com.google.inject.internal.MoreTypes.ParameterizedTypeImpl(null, MyClass.class, a, b); 

Tạo một TypeLiteral từ nó:

TypeLiteral typeLiteral = TypeLiteral.get(type); 

Bây giờ tạo Ví dụ tiêm:

return (MyClass<A,B>) injector.getInstance(Key.get(typeLiteral)) 

Trên thực tế bạn muốn thực hiện ParameteriedType mình:

final Type[] types = {a, b}; 
ParameterizedType type = ParameterizedType() { 
    @Override 
    public Type[] getActualTypeArguments() { 
    return types; 
    } 

    @Override 
    public Type getOwnerType() { 
    return null; 
    } 

    @Override 
    public Type getRawType() { 
    return MyClass.class; 
    }; 
} 

EDIT: Trong thực tế, bạn có thể sử dụng:

Types.newParameterizedType(MyClass.class,a,b) 

thấy Guice module with type parameters

+0

Người đàn ông làm việc tuyệt vời, nó hoạt động! Cảm ơn bạn ! – overflow

0

Thực tế, tôi nghĩ điều đó là không thể. Generics không được hợp nhất khi chạy. Điều này có nghĩa là thông tin không có trong thời gian chạy. Vì vậy, nó không quan tâm những gì loại chung bạn cung cấp cho nó.

Vì vậy, tôi nghĩ phương pháp này là không cần thiết. Đơn giản chỉ cần một cái gì đó như thế này:

public MyClass<?,?> getMyClass(Injector injector, Class<?> a, Class<?> b) 
{ 
    return new MyClass(); 
    // Or maybe something like this, if you use custom constructors 
    // return injector.getInstance(); 
} 

Kể từ MyClass là một giao diện, những gì bạn muốn đạt được là hoàn toàn vô dụng và bất khả thi. Làm thế nào để bạn muốn khởi tạo một đối tượng với một hành vi cụ thể khi bạn chỉ xác định loại param và kiểu trả về.
Tôi nghĩ bạn nên cố gắng tìm một cách làm việc khác.

+0

Tôi đã thêm chi tiết vào câu hỏi của tôi, cảm ơn – overflow

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