Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8272077

Cannot assign method reference to Generic Function Interface

XMLWordPrintable

    • generic
    • generic

      A DESCRIPTION OF THE PROBLEM :
      In the following example, I try to assign function references and a lambda to generic functional interfaces.

      In the first example, I successfully assign a reference of bar to Function0 generic functional interface.
      In the second example, both type arguments include wildcards with extends, and I managed to assign a lambda.
      In the last example, I tried to assign a reference of foo to Function1 (which is similar to the previous lambda), but the compiler reports an error message. More specifically, it reports: "incompatible types: Number cannot be converted to Short", if I replace the first type argument to ? extends Short, the program compiles.

      It looks to me that there is an inconsistency between handling lambdas and function references. Is there something that I am missing here?

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      javac Test.java

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Compile successfully
      ACTUAL -
      Test.java:15: error: incompatible types: invalid method reference
          Function1<? extends Number, ? extends Number> f2 = Test::foo; // does not work
                                                             ^
          incompatible types: Number cannot be converted to Short
      1 error

      ---------- BEGIN SOURCE ----------
      class Test {
        public static Short foo(Short x) {
            return x;
        }

        public static Short bar() {
            Short x = 1;
            return x;
        }

        public static void main(String[] args) {
          Function0<? extends Number> f = Test::bar;

          Function1<? extends Number, ? extends Number> f1 = (Short x) -> x; // works
          Function1<? extends Number, ? extends Number> f2 = Test::foo; // does not work
        }
      }

      interface Function0<R> {
        public R apply();
      }

      interface Function1<P, R> {
        public R apply(P x);
      }

        public static Short bar() {
            Short x = 1;
            return x;
        }

        public static void main(String[] args) {
          Function0<? extends Number> f = Test::bar;

          Function1<? extends Number, ? extends Number> f1 = (Short x) -> x; // works
          Function1<? extends Short, ? extends Number> f2 = Test::foo; // does not work
        }
      }

      interface Function0<R> {
        public R apply();
      }

      interface Function1<P, R> {
        public R apply(P x);
      }

      ---------- END SOURCE ----------

      FREQUENCY : always


            adev Anupam Dev
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: