Java和泛型类型边界 一些背景

Java和泛型类型边界 一些背景,java,generics,lambda,java-8,Java,Generics,Lambda,Java 8,我正在开发一个基于Lambda表达式的小型DI容器。 我有代表lambda的接口: @FunctionalInterface public interface LambdaOp<T> { T resolve(); } 它工作正常,很好,因为编译器不会让我做这样的事情: container.bind( FooInterface.class, () -> new BarImplementation() //compiler error; Bar does

我正在开发一个基于Lambda表达式的小型DI容器。 我有代表lambda的接口:

@FunctionalInterface
public interface LambdaOp<T> {
    T resolve();
}
它工作正常,很好,因为编译器不会让我做这样的事情:

container.bind(
    FooInterface.class,
    () -> new BarImplementation() //compiler error; Bar does not implement Foo
);
问题 绑定映射本身并不保证LambdaOp将具有扩展用作键的类的泛型类型

private final Map<Class<?>, LambdaOp<?>> bindings;
我认为bind方法签名足以保证内聚性(是吗?),但仍然感觉到一些不好的味道

有没有办法以更具凝聚力的方式实施它

编辑:


完整的代码位于。最近我做了很多更改,README.md有点过时。

没有办法做到这一点,编译器自然会自行判断并保证泛型类型是正确的。但是,您可以告诉编译器闭嘴,在这种情况下,这样做是合适的,因为您的实现确实提供了相关的保证

public <T> T resolve (Class<T> clazz) {
    @SuppressWarnings("unchecked")
    LambdaOp<? extends T> lambda = (LambdaOp<? extends T>) bindings.get(clazz);
    return lambda.resolve(); 
}
public T解析(类clazz){
@抑制警告(“未选中”)

LambdaOp为什么不使用
类clazz
键进行强制转换呢?您的逻辑已经保证强制转换始终有效

return clazz.cast( lambda.resolve() );
编辑以澄清: 使用
对象可以在没有警告的情况下工作,而简单泛型强制转换不能工作的原因是,在使用泛型强制转换的运行时,泛型类型也可能被擦除为
对象
,因此编译器无法保证强制转换将适用于预期类型n另一方面,将拥有执行强制转换所需的所有信息,因此编译器可以安全地将其用于泛型类型


假设你当然不想和泛型混淆。

据我所知,这是没有办法的。我不认为这个警告是一个问题,因为它隐藏在你的实现后面。添加到映射的唯一方法是通过您的
bind
方法。在Java中,任何时候您强制转换到不可恢复的泛型类型时,都会收到未经检查的警告。这是因为类型信息在运行时不存在,Java环境无法保证强制转换的类型安全。类似的情况是无法帮助的…如果你分析你自己的代码,并且可以证明它是类型安全的,那么就不要发出警告。很好。我正在使用这个项目作为学习该语言的工具,从更有经验的开发人员那里得到一些反馈总是很好的。顺便说一句,你的
LambdaOp
接口可以被接受的标准建议所取代。看起来是这样的不会发出任何警告,在这种情况下应该是完美的。
return (T) lambda.resolve();
public <T> T resolve (Class<T> clazz) {
    @SuppressWarnings("unchecked")
    LambdaOp<? extends T> lambda = (LambdaOp<? extends T>) bindings.get(clazz);
    return lambda.resolve(); 
}
return clazz.cast( lambda.resolve() );