繁体   English   中英

检查参数化泛型抽象类的强制转换为其实现

[英]Checked cast of parametrized generic abstract class to it's implementation

我有一个复杂的方法,该方法返回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)声明局部变量时assertDiffType(result, NewCurrentVersionDiffResult.class)它会生成

NewCurrentVersionDiffResult newCurrentVersionDiffResult =

并不是

NewCurrentVersionDiffResult<MockVersion, String> newCurrentVersionDiffResult = 

同样,警告是在调用assertDiffType()方法时,而不是在方法本身上。

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

不幸的是,您不能只执行NewCurrentVersionDiffResult<MockVersion, String>.class 在这里回答了如何处理这个问题 ; 长话短说,您应该使用Guava库中的 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>>() {});

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM