我在代码中面临一个令人困惑的问题。
我有一种方法是签名
public <T extends Measure> void sendNewMeasure(Class<T> type, T measure);
Run Code Online (Sandbox Code Playgroud)
在另一个类中,我有此方法,该方法调用上一个方法:
public <T extends Measure> void onNewMeasure(NewMeasureEvent<T> event) {
T measure = event.getMeasure();
APIInterface.getInstance().sendNewMeasure(measure.getClass(), measure);
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是Wrong argument type, found 'T', required <? extends com.blablabla.Measure>但我不明白为什么,因为测量对象的类型为T,扩展了Measure。
有什么办法可以解决此问题,最重要的是,为什么它不起作用?
谢谢 !
编辑:
这是sendNewMeasure方法的实现:
public <T extends Measure> void sendNewMeasure(Class<T> type, T measure) {
String measureType = measure.getJSONMeasureTypeName();
List<T> measures = T.find(type, measure.timestamp, true, false);
measures.add(measure);
sendMeasures(siteId, sensorId, measureType, measures);
}
Run Code Online (Sandbox Code Playgroud)
编辑2:这是find方法签名,我无法更改:
public static <T> List<T> find(Class<T> type, int timestamp, boolean includeStart, boolean inclueEnd);
Run Code Online (Sandbox Code Playgroud)
类型.getClass()不是您想的那样。.getClass()返回Class<? extends |X|>,其中|X|是对其调用的表达式的静态类型的擦除。在这种情况下,measure具有静态类型T,具有擦除Measure,所以measure.getClass()具有type Class<? extends Measure>,即具有type ,即type参数是的未知子类型Measure,并且.sendNewMeasure(measure.getClass(), measure)编译器无法保证measure(of typeT)是该未知类型的实例。
基本上,问题是.getClass()丢失类型信息。它的返回类型没有直接链接到被调用的事物的类型,因为Java类型系统无法表达“被调用的事物的真实运行时类型”的概念。但是,从直观上讲,您知道具有当前签名的方法的调用.sendNewMeasure(measure.getClass(), measure)是类型安全的,因为的类型measure.getClass()实际上应该是的实际运行时类是Class<U>where ,并且您知道这显然是同一类型的实例,因此存在某种类型的参数,此参数(不一定与相同)是对其进行调用的UmeasuremeasureUUT.sendNewMeasure()类型检查的,但是问题是如何在不使用未经检查的操作的情况下说服编译器。
问题是所返回的类型measure.getClass()与的类型未充分链接measure。重新链接它们的一种方法是使用类,使用类的方法将对象转换为其类型(将始终成功).cast()。但它并不能帮助与类型的表达式要做到这一点Class<? extends Measure>,因为导致的.cast()就是? extends Measure刚刚降级到Measure,所以我们还没有这两种类型之间的联系。我们需要类型的真实名称,而不是通配符,以便我们维护此链接。将通配符转换为命名类型的方法是capture,这需要将其传递给通用方法:
public <T extends Measure> void onNewMeasure(NewMeasureEvent<T> event) {
T measure = event.getMeasure();
helper(measure.getClass(), measure);
}
private <U extends Measure> void helper(Class<U> clazz, Measure measure) {
U castedMeasure = clazz.cast(measure);
APIInterface.getInstance().sendNewMeasure(clazz, castedMeasure);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1287 次 |
| 最近记录: |