Java泛型警告需要大师冥想

时间:2017-07-10 19:51:24

标签: java android generics warnings aide-ide

我有一些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 个答案:

答案 0 :(得分:1)

map应该只有T2作为类型参数,而不是T。现在TT类隐藏Seek<T>,也就是说,你有两个名为T的类型变量,它们实际上是不同的,你不需要它。

答案 1 :(得分:1)

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

  1.   

    类型安全:通过varargs参数o潜在的堆污染   在abstract <T,T2> void map(Func<T,T2> call);

  2.   

    类型参数T将类型T隐藏在seek(some).map(c);

  3.   

    类型安全:在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' } }

    为varargs参数创建X1的通用数组
  4. 可以清除警告 A.从泛型中取出varargs参数,如:

      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
      }
    }
    

    B中。明确定义数组,如:

    S[] o

    但是,S... oMat camMtx = new Mat(1, 5, CvType.Cv64fc1, new Scalar(0)); Mat distCoef = new Mat(3, 3, CvType.Cv64fc1, new Scalar(0)); MatOfPoint2f uncalibpoints = new MatOfPoint2f(); MatOfPoint2f calibpoints = new MatOfPoint2f(); List<Point> points = new List<Point>(); points.Add(center); //Some previously stored point points.Add(apex1); //Some previously stored point points.Add(apex2); //Some previously stored point points.Add(apex3); //Some previously stored point uncalibpoints.FromList(points); //Convert list of points to MatofPoint2f Console.WriteLine(uncalibpoints.Channels()); Console.WriteLine(uncalibpoints.Size()); Console.WriteLine(uncalibpoints.GetType()); //Manually setting the matrix values distCoef.Put(0, 0, 0.51165764); distCoef.Put(0, 1, -1.96134156); distCoef.Put(0, 2, 0.00600294); distCoef.Put(0, 3, 0.00643735); distCoef.Put(0, 4, 2.59503145); camMtx.Put(0, 0, 1551.700); camMtx.Put(0, 1, 0.0); camMtx.Put(0, 2, 962.237163); camMtx.Put(1, 0, 0.0); camMtx.Put(1, 1, 1536.170); camMtx.Put(1, 2, 589.418432); camMtx.Put(2, 0, 0.0); camMtx.Put(2, 1, 0.0); camMtx.Put(2, 2, 1.0); Imgproc.UndistortPoints(uncalibpoints, calibpoints, camMtx, distCoef);` 完全不同。它只能显式地使用Array。也许你需要重新考虑你的设计?

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

答案 2 :(得分:0)

我从编译代码中获得的警告与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);
    }
}

答案 3 :(得分:0)

T方法中将T1更改为map。 您也将获得通用数组警告。这是修改后的版本,没有任何警告:

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); 
    }
}
相关问题