0

我有一些类似于以下代码段的 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 的答案后,我修复了代码中的一个错误。

4

4 回答 4

1

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

于 2017-07-10T19:54:25.520 回答
1

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

  1. 类型安全:通过 varargs 参数 o 造成的潜在堆污染abstract <S> Seek<S> seek(S... o);

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

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

它可以清除警告 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[] o完全不一样S... o。它只能显式地采用 Array。也许您需要重新考虑您的设计?

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

于 2017-07-10T20:34:10.320 回答
0

我从编译您的代码中得到的警告与从该seek(S...)方法创建通用数组有关。

如果您可以将其更改为 a 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);
    }
}
于 2017-07-10T20:01:33.287 回答
0

改成T方法T1map。您还将获得通用数组警告。这是没有警告的修改版本:

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); 
    }
}
于 2017-07-10T20:01:45.830 回答