2014-09-04 33 views
1

這裏是我的StatusMapper接口看起來像:如何讓Guice MapBinder真的類型安全?

public interface StatusMapper<T extends Throwable> { 
    Status map(final T exception); 
} 

這裏是我的MapBinder:

TypeLiteral<Class<? extends Throwable>> exceptionType = new TypeLiteral<Class<? extends Throwable>>() { }; 
    TypeLiteral<StatusMapper<? extends Throwable>> mapperType = new TypeLiteral<StatusMapper<? extends Throwable>>() { }; 

    MapBinder<Class<? extends Throwable>, StatusMapper<? extends Throwable>> exceptionBinder = MapBinder.newMapBinder(binder(), exceptionType, mapperType); 

    exceptionBinder.addBinding(IOException.class).to(IOExceptionMapper.class); 
    exceptionBinder.addBinding(SQLException.class).to(SQLExceptionMapper.class); 
    ... 

這是如何將這些ExceptionMappers的一個樣子:(簡體)

public class IOExceptionMapper implements StatusMapper<IOException> { 
    @SuppressWarnings("unused") 
    private static final Logger logger = LoggerFactory.getLogger(IOExceptionMapper.class); 

    @Override 
    public Status map(final IOException exception) { 
     return new Status(100); 
    } 
} 

到目前爲止工作正常,但我必須注意IOException綁定到IOExceptionMapper。如果我綁定exceptionBinder.addBinding(IOException.class).to(SQLExceptionMapper.class); typechecker(編譯器)不抱怨,但它打破了整個應用程序 - 任何提示?

[更新] 根據The111的答案我創建ExceptionBinder

public class ExceptionBinder { 
    private final MapBinder<Class<? extends Throwable>, StatusMapper<? extends Throwable>> exceptionBinder; 

    public ExceptionBinder(final Binder binder) { 
     final TypeLiteral<Class<? extends Throwable>> exceptionType; 
     final TypeLiteral<StatusMapper<? extends Throwable>> mapperType; 

     exceptionType = new TypeLiteral<Class<? extends Throwable>>() {}; 
     mapperType = new TypeLiteral<StatusMapper<? extends Throwable>>() {}; 

     exceptionBinder = MapBinder.newMapBinder(binder, exceptionType, mapperType); 
    } 

    public <T extends Throwable> void bind(Class<T> exceptionClass, Class<? extends StatusMapper<T>> mapperClass) { 
     exceptionBinder.addBinding(exceptionClass).to(mapperClass); 
    } 
} 

這是我的吉斯 - 模塊的樣子:

final ExceptionBinder eb = new ExceptionBinder(binder()); 
eb.bind(IOException.class,IOExceptionMapper.class); 
eb.bind(SQLException.class,SQLExceptionMapper.class); 

回答

1

你的問題似乎可能與此相關的一個: Java map with values limited by key's type parameter

什麼如果你包裹吉斯MapBinder在自己TypeSafeMapBinder並給該類中的方法,如:

void addToBinder(Class<T extends Throwable> eClass, 
       Class<? extends StatusMapper<T>> mClass) { 
    getWrappedBinder().addBinding(eClass, mClass); 
} 

我還沒有測試,所以請讓我知道你的結果。

+0

酷男 - thx!只有丟失。我用解決方案更新了我的問題。 – 2014-09-04 10:52:45