Java - 获得比#34; Class <! - ? - >&#34;更具体的类型。参数化通用类

时间:2016-01-13 12:58:32

标签: java generics

我有一个基本接口,使用扩展相同基接口的类型R进行参数化:

public interface IWidget<R extends IWidget<R>> {}

然后以相同的方式参数化另一个接口:

public interface IWidgetManager<R extends IWidget<R>> {}

最后,一个类实现了第二个接口。该类将在声明时收到IWidget 实现类:

public class MyWidgetManager<R extends IWidget<R>> implements IWidgetManager<R> {}

我的问题:

我们可以用来指定MyWidgetManager的更具体类型是什么?

Class<?>当然有效:

public Class<?> ok() {
    return MyWidgetManager.class;
}

但它非常通用,我想要更具体的东西...

这些尝试无法编译:

public Class<? extends IWidgetManager<?>> fails() {
    return MyWidgetManager.class;
}

==&GT; 类型不匹配:无法转换为Class&lt; MyWidgetManager&gt;到班级&lt;?扩展IWidgetManager&lt;?&gt;&gt;

public <R extends IWidget<?>> Class<? extends IWidgetManager<R>> fails() {
    return MyWidgetManager.class;
}

==&GT; 类型不匹配:无法转换为Class&lt; MyWidgetManager&gt;到班级&lt;?扩展IWidgetManager&lt; R&gt;&gt;

public <R extends IWidget<R>> Class<? extends IWidgetManager<R>> fails() {
    return MyWidgetManager.class;
}

==&GT; 类型不匹配:无法转换为Class&lt; MyWidgetManager&gt;到班级&lt;?扩展IWidgetManager&lt; R&gt;&gt;

public Class<? extends IWidgetManager<? extends IWidget<?>>> fails() {
    return MyWidgetManager.class;
}

==&GT; 类型不匹配:无法转换为Class&lt; MyWidgetManager&gt;到班级&lt;?扩展IWidgetManager&lt;?扩展IWidget&lt;?&gt;&gt;&gt;

我是否可以为Class<?>获取比MyWidgetManager.class更具体的类型?

更新: 我更改了界面的名称。最后一堂课是而不是一个Widget本身,在我原来的问题中并不清楚......对不起这个混乱。

更新2:

事实上,在使用具体类型时,事情会更容易。

这对我目前的情况非常具体,但我认为我会解决我的问题&#34;通过将MyWidgetManager<R extends IWidget<R>> implements IWidgetManager<R>转换为无法实现任何内容的WidgetManagerBase。然后使用具体的Widget类提供默认实现。最后,get方法可以轻松覆盖(从一开始,这是我的主要目标!)。所以:

public interface IWidget<R extends IWidget<?>> {}
public interface IWidgetManager<R extends IWidget<R>> {}
public class WidgetManagerBase {}

// Default implementation
public class WidgetA implements IWidget<WidgetA> {}
public class AWidgetManager extends WidgetManagerBase implements IWidgetManager<WidgetA> {}

// default get method
public Class<? extends IWidgetManager<?>> getWidgetManagerClass() {
    return AWidgetManager.class;
}

//然后可以使用以下方法覆盖默认的get方法:

public class WidgetB implements IWidget<WidgetB> {}
public class BWidgetManager extends WidgetManagerBase implements IWidgetManager<WidgetB> {}

@Override
public Class<? extends IWidgetManager<?>> getWidgetManagerClass() {
    return BWidgetManager.class;
}

2 个答案:

答案 0 :(得分:3)

由于Java Type Erasure MyWidget.class的最具体匹配是Class<? extends IWidget>

public Class<? extends IWidget> test() {
    return MyWidget.class;
}

如果你想要比具体的类型参数扩展MyWidget更具体:

public class ConcreteBaseWidget implements IBaseWidget<ConcreteBaseWidget> {
}

public class ConcreteWidget extends MyWidget<ConcreteBaseWidget> {
}

然后所有这些方法都会起作用:

public Class<? extends IWidget<? extends IBaseWidget<? extends IBaseWidget<?>>>> test1() {
    return ConcreteWidget.class;
}

public Class<? extends IWidget<? extends IBaseWidget<ConcreteBaseWidget>>> test2() {
    return ConcreteWidget.class;
}

public Class<? extends IWidget<? extends ConcreteBaseWidget>> test3() {
    return ConcreteWidget.class;
}

答案 1 :(得分:2)

我真的认为你只是在寻找

public interface IBaseWidget<R extends IBaseWidget<R>> {}

public interface IWidget<R extends IWidget<R>> extends IBaseWidget<R> {} //not sure about this one.

public class MyWidget implements IWidget<MyWidget> {}

通过这种方式,您可以将MyWidget.class视为Class<R>

这是您正在寻找的,还是我误解了您的意图?

修改

在那种情况下,

public interface IWidgetManager<R extends IWidget<R>> {}

public class MyWidgetManager<R extends IWidget<R>> implements IWidgetManager<R> {}

可以替换为

public interface IWidgetManager<R extends IWidget<R>, WM extends IWidgetManager<R, WM>> {}

public class MyWidgetManager<R extends IWidget<R>> implements IWidgetManager<R, MyWidgetManager> {}

因为您 能够以MyWidgetManager.class的身份访问Class<WM>