[英]Calling a generic method with a generic parameter doesn't work without cast
First of all, sorry for the title but even after minutes of thinking, this was best I found. 首先,对标题感到抱歉,但是即使经过几分钟的思考,我仍然发现这是最好的。 Here the situation:
这里的情况:
I have an abstract 'Factory' class. 我有一个抽象的“工厂”类。 It takes T as return type of the instance.
它以T作为实例的返回类型。
abstract class Factory<T> {
abstract T getInstance();
}
Now I add an interface to mark classes which have a factory. 现在,我添加了一个接口来标记具有工厂的类。 This interface is parameterized with the Factory itself.
该接口是使用Factory本身进行参数化的。
interface Factorized<TFACTORY extends Factory<?>> {}
Now I can mark classes that have a factory. 现在,我可以标记具有工厂的类。
class BaseImpl1 implements Factorized<BaseImpl1Factory> {}
class BaseImpl1Factory extends Factory<BaseImpl1> {
@Override BaseImpl1 getInstance() { return null; /* TODO */}
}
With a small method and some reflection I can get an instance of the factory by passing the base class itself. 通过一个小的方法和一些反思,我可以通过传递基类本身来获得工厂的实例。
<RETURNED_FACTORY extends Factory<?>> RETURNED_FACTORY getFactory(Class<? extends Factorized<RETURNED_FACTORY>> clazz) {
/* TODO */
}
// usage:
BaseImpl1Factory factory = getFactory(BaseImpl1.class);
This works fine until the point where I add generics in the base class . 直到我在基类中添加泛型为止,它都可以正常工作。
See the full example: 查看完整的示例:
public class Test {
void test() {
getFactory(BaseImpl1.class).someMethod1();
getFactory(BaseImpl2.class).someMethod2(); // <-- compile error
getFactory((Class<? extends Factorized<BaseImpl2Factory>>) BaseImpl2.class).someMethod2(); // <-- it works with cast
getFactory(SubBase2Impl.class).someMethod2(); // only for info.. this works
}
<RETURNED_FACTORY extends Factory<?>> RETURNED_FACTORY getFactory(Class<? extends Factorized<RETURNED_FACTORY>> clazz) {
/* TODO */
}
}
abstract class Factory<T> {
abstract T getInstance();
}
interface Factorized<TFACTORY extends Factory<?>> {}
// ****** implementation without generic *******
class BaseImpl1 implements Factorized<BaseImpl1Factory> {}
class BaseImpl1Factory extends Factory<BaseImpl1> {
void someMethod1(){}
@Override BaseImpl1 getInstance() { /* TODO */ }
}
// ****** implementation with generic *******
class BaseImpl2<T> implements Factorized<BaseImpl2Factory> {}
class BaseImpl2Factory extends Factory<BaseImpl2<?>> {
void someMethod2(){}
@Override BaseImpl2<?> getInstance() { /* TODO */ }
}
class SubBase2Impl extends BaseImpl2<String>{}
It works when I cast it but why do I have to? 它在我投放时有效,但是为什么必须这样做? What do I have to change to access the factory without casting?
在不进行铸造的情况下,我必须更改什么才能进入工厂?
Hints: 提示:
You're looking for what's called a self-type . 您正在寻找所谓的自我类型 。 Here's an example:
这是一个例子:
interface Factory<T> { T getInstance(); }
interface Buildable<T> { Factory<T> getFactory(); }
class CanBuild implements Buildable<CanBuild> {
@Override
public Factory<CanBuild> getFactory() {
return null; // TODO
}
}
The Buildable
interface ( Factorized
in your example) indicates a type that can build T
s. Buildable
接口(在您的示例中为Factorized
)指示可以构建T
的类型。 While T
could be any type, you'll often use it as a self-type by making T
the same type as the class being defined. 尽管
T
可以是任何类型,但是通过使T
与要定义的类相同的类型,您经常将其用作自类型。
Self-types are commonly used when defining fluent interfaces . 自定义类型通常用于定义流畅的界面 。 The Truth library uses them heavily, so you might like to poke around their code to see more examples.
Truth库大量使用它们,因此您可能想看看它们的代码以查看更多示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.