Search code examples
javaandroidgenericswarningsaide-ide

Java generics warning requiring guru meditation


I have some Java code like the following snippet (the example is simplified from the original code). A yellow squiggle and warning message appear, as indicated by the code comment below. The message is: "This method invocation is unsafe since the passed arguments may be of a wrong type."

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

Why does the warning appear? What is the best way to fix this?

Note: I'm using the AIDE development environment for Android.

EDIT: I fixed an error in the code after reading the answer from @tsolakp and @LouisWasserman.


Solution

  • Actually there are three warnings in that code:

    1. Type safety: Potential heap pollution via varargs parameter o at abstract <S> Seek<S> seek(S... o);

    2. The type parameter T is hiding the type T at abstract <T,T2> void map(Func<T,T2> call);

    3. Type safety: A generic array of X1 is created for a varargs parameter at seek(some).map(c);

    It can be clean of warnings A. take out varargs parameter from generic like:

    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. define arrays explicitly like:

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

    but, S[] o is quite not the same as S... o. It can take only Array explicitly. Maybe you need to reconsider your design?

    IMHO: I really do not understand needs to have that many Generic type parameters at the same time on class and methods level...