1

I have the below test class in my java code:

 Function<? super Either<? extends Object, ? extends Object>, ? super Either<? extends Object, ? extends Object>> test = new Function<Either<Integer, Integer>, Either<Integer, Integer>>() {
        @Override
        public Either<Integer, Integer> apply(Either<Integer, Integer> integers) {
            return integers;
        }
 }

Documentation for Either can be found here: http://static.javadoc.io/io.javaslang/javaslang/2.0.2/javaslang/control/Either.html.

But I get the following compile error (Java 8)

Error:(77, 129) java: incompatible types: 
<anonymous java.util.function.Function<javaslang.control.Either<java.lang.Integer,java.lang.Integer>,javaslang.control.Either<java.lang.Integer,java.lang.Integer>>> 
cannot be converted to 
java.util.function.Function<? super javaslang.control.Either<? extends java.lang.Object,? extends java.lang.Object>,? super javaslang.control.Either<? extends java.lang.Object,? extends java.lang.Object>>

I am new to Java and am not sure what is wrong here. Any help is much appreciated.

I understand this code does not make sense and that is not how I am using it really. I am actually trying to pass a Function to an internal library. But I should not be getting that compile error where Either cannot be converted to ? super Either

Thanks!!

Rohit
  • 21
  • 4
  • 4
    You are new to java, but you try to use generics in a very advanced way; my suggestion: step back and look into the things that newbies to the Java language would start with ;-) – GhostCat Feb 20 '17 at 08:51
  • 1
    Tip: `? extends Object` is synonymous with `?`. – shmosel Feb 20 '17 at 08:52
  • Why don't you just declare your variable as the type you create? I.e. `Function, Either>` – Andreas Feb 20 '17 at 08:58

1 Answers1

0

The reason it doesn't work is because ? super Either<? extends Object, ? extends Object> (which is equivalent to ? super Either<?, ?>) must be able to accept any type of Either. For example, the following must compile

Either<Long, Long> either = ...
test.apply(either);

since Either<Long, Long> is a subclass of Either<?, ?>. But your implementation is only capable of processing a specific subtype: Either<Integer, Integer>.

Here's a simpler demonstration of the same problem:

Lis<? super Number> numbers = new ArrayList<Integer>();

This does not compile because the list must be of a type that can accept any Number, not just Integer.

The ideal solution for your case depends on what exactly you're trying to do, which isn't entirely clear from the question. The closest I can get to your attempt is this:

Function<? super Either<Integer, Integer>, ? extends Either<?, ?>> test = ...

Note the use of super in the first parameter and extends in the second parameter. This follows the principle of Producer extends, Consumer super.

Community
  • 1
  • 1
shmosel
  • 49,289
  • 6
  • 73
  • 138