2017-08-08 33 views
1

我有一个复杂的方法返回DiffResult<T, V>的不同实现。我想对执行进行检查转换,以便调用它的方法并声明结果。检查了参数化泛型抽象类的转换为它的实现

// this is ok 
DiffResult<MockVersion, String> result = calculator.diff(a, b); 

// this is problem 
NewCurrentVersionDiffResult<MockVersion, String> newCurrentVersionDiffResult = assertDiffType(result, NewCurrentVersionDiffResult.class); 

// this is ok 
Assert.assertEquals("expected", newCurrentVersionDiffResult.getNewValue()); 

NewCurrentVersionDiffResult具有以下标题

public class NewCurrentVersionDiffResult<T extends ProductDataVersion<T>, V> extends DiffResult<T, V> 
{ /* ... */ } 

我已经试过这

private static <D extends DiffResult<T, V>, T extends ProductDataVersion<T>, V> D assertDiffType(final DiffResult<T, V> result, final Class<D> type) 
{ 
    Assert.assertThat(result, CoreMatchers.instanceOf(type)); 
    return type.cast(result); 
} 

这个执行时的作品,但有报道编译警告

[WARNING] VersionDiffCalculatorTest.java:[34,102] unchecked method invocation: method assertDiffType in class VersionDiffCalculatorTest is applied to given types 
    required: DiffResult<T,V>,java.lang.Class<D> 
    found: DiffResult<VersionDiffCalculatorTest.MockVersion,java.lang.String>,java.lang.Class<NewCurrentVersionDiffResult> 
[WARNING] VersionDiffCalculatorTest.java:[34,102] unchecked conversion 
    required: NewCurrentVersionDiffResult<VersionDiffCalculatorTest.MockVersion,java.lang.String> 
    found: NewCurrentVersionDiffResult 

我会就像有工作,没有警告。

我知道@SuppressWarnings("unchecked"),我在其他地方自己使用它。但是,这种情况下显然是坏了,因为当我告诉IDEA从assertDiffType(result, NewCurrentVersionDiffResult.class)声明局部变量它产生

NewCurrentVersionDiffResult newCurrentVersionDiffResult = 

,而不是

NewCurrentVersionDiffResult<MockVersion, String> newCurrentVersionDiffResult = 

还警告后的assertDiffType()方法的调用,而不是该方法本身。

回答

2

您正在将NewCurrentVersionDiffResult.class传递给Class<D>参数的方法,这就是它如何确定D的类型,它也是返回类型。请注意那里的NewCurrentVersionDiffResult缺少通用参数。这就是为什么该方法返回一个原始类型。

不幸的是,你不能只是做NewCurrentVersionDiffResult<MockVersion, String>.class。如何处理这个问题is answered here;长话短说,你应该从Guava library使用TypeToken

@SuppressWarnings("unchecked") 
private static <D extends DiffResult<T, V>, T extends ProductDataVersion<T>, V> D assertDiffType(final DiffResult<T, V> result, final TypeToken<D> type) { 
    Assert.assertThat(result, CoreMatchers.instanceOf(type.getRawType())); 
    return (D) result; 
} 

有了这个,你可以这样做:

NewCurrentVersionDiffResult<MockVersion, String> newCurrentVersionDiffResult = assertDiffType(result, 
     new TypeToken<NewCurrentVersionDiffResult<MockVersion, String>>() {}); 
+0

谢谢,这个作品! –

0

使用所需类型的最佳方式,但您可以用此@SuppressWarnings(“unchecked”)来抑制警告,在少数情况下我们无法做很多事情,如果不可能,我们必须使用@SuppressWarnings(“unchecked”)

+0

谢谢,但这不是解决问题的办法,我已经更新的问题。 –