Java 泛型警告需要上师冥想



我有一些Java代码,如下面的代码片段(该示例是从原始代码简化而来的(。将显示黄色波浪线和警告消息,如下面的代码注释所示。消息是:"此方法调用不安全,因为传递的参数可能属于错误的类型。

abstract class Seek<T> {
abstract <S> Seek<S> seek(S... o);
abstract <T2> void map(Func<T,T2> call);
interface Func<I,O> {
public O call(I x);
}
public <X2> void go(Func<T,X2> c, T some) {
seek(some).map(c); // <- yellow squiggle here on 'c'
}
}

为什么会出现警告?解决此问题的最佳方法是什么?

注意: 我正在使用适用于Android的AIDE开发环境。

编辑:我在阅读@tsolakp和@LouisWasserman的答案后修复了代码中的错误。

实际上,该代码中有三个警告:

  1. 类型安全:通过变量参数o进行潜在的堆污染 在abstract <S> Seek<S> seek(S... o);

  2. 类型参数 T 在abstract <T,T2> void map(Func<T,T2> call);处隐藏类型 T

  3. 类型安全:在seek(some).map(c);处为 varargs 参数创建 X1 的泛型数组

它可以清除警告 A. 从泛型中取出 varargs 参数,例如:

abstract class Seek<T> {
abstract <S> Seek<S> seek(S o); // <- no more yellow squiggle
abstract <T1,T2> void map(Func<T1,T2> call); // <- no more yellow squiggle
interface Func<I,O> {
public O call(I x);
}
public <X1,X2> void go(Func<X1,X2> c, X1 some) {
seek(some).map(c); // <- no more yellow squiggle here on 'c'
}
}

B. 显式定义数组,如下所示:

abstract class Seek<T> {
abstract <S> Seek<S> seek(S[] o);        // <- no more yellow squiggle
abstract <T2> void map(Func<T,T2> call); // <- no more yellow squiggle
interface Func<I,O> {
public O call(I x);
}
public <X1,X2> void go(Func<X1,X2> c, X1[] some) {
seek(some).map(c); // <- no more yellow squiggle
}
}

但是,S[] oS... o完全不同. 它只能显式地采用数组。也许您需要重新考虑您的设计?

恕我直言:我真的不明白需要在类和方法级别同时拥有那么多泛型类型参数......

map应该只将T2作为类型参数,而不是T。 现在,TSeek<T>类中遮蔽了T,也就是说,您有两个名为 T 的类型变量实际上是不同的,您不希望这样。

我从编译代码中获得的警告与从seek(S...)方法创建的泛型数组有关。

如果可以将其更改为List<S>,则可以使用Arrays.asList()调用它:

abstract class Seek<T> {
abstract <S> Seek<S> seek(List<S> o);
// ...
public <X1,X2> void go(Func<X1,X2> c, X1 some) {
seek(Arrays.asList(some)).map(c);
}
}

map方法中将T更改为T1。 您还将收到通用数组警告。这是没有警告的修改版本:

abstract static class Seek<T> {
abstract <S> Seek<S> seek(List<S> s);
abstract <T1,T2> void map(Func<T1, T2> call);
interface Func<I,O> {
public O call(I x);
}
public <X1,X2> void go(Func<X1,X2> c, X1 some) {
seek( Arrays.asList(some) ).map(c); 
}
}

经过一些评论后,OP可能打算使map方法与类泛型类型绑定Seek。如果是这种情况,我们可以按照@Louis Wasserman和@Andy Turner的建议使用此解决方案:

abstract static class Seek<T> {
abstract <S> Seek<S> seek(List<S> s);
abstract <T2> void map(Func<T, T2> call);
interface Func<I,O> {
public O call(I x);
}
public <X1,X2> void go(Func<X1,X2> c, X1 some) {
seek( Arrays.asList(some) ).map(c); 
}
}

最新更新