LINUX.ORG.RU

Java 8 Lambda


0

1

Всем привет!

Вот такой незамысловатый код:

public class Test {
    public static void main(String[] args) {
        final Function2<Integer, Integer, Integer> add = (x, y) -> (x + y);
        final Function1<Integer, Integer> inc = (x) -> (add.apply(x, 1));
        System.out.println(inc.apply(0));
    }

    @FunctionalInterface
    public static interface Function1<R, A> {
        R apply(A input);
    }

    @FunctionalInterface
    public static interface Function2<R, A1, A2> {
        R apply(A1 input1, A2 input2);
    }
}

cкомпилировался но...

Exception in thread «main» java.lang.VerifyError: Bad return type Exception Details: Location: Test.lambda$main$1(LTest$Function2;Ljava/lang/Integer;)Ljava/lang/Integer; @11: areturn Reason: Type 'java/lang/Object' (current frame, stack[0]) is not assignable to 'java/lang/Integer' (from method signature) Current Frame: bci: @11 flags: { } locals: { 'Test$Function2', 'java/lang/Integer' } stack: { 'java/lang/Object' } Bytecode: 0000000: 2a2b 04b8 0005 b900 0803 00b0

at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:259) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:113)

Я отправил баг-репорт 10/19/12 на что получил подтверждение - «Your Report (Review ID: 2361784)». В итоге баг-репорт похоже не приняли, скорее всего из-за того, что я плохо его составил.

Суть в том, что уже developer preview, а ошибка никуда не делась. Если такой код не должен работать, то, наверно, он не должен и компилироваться.

Буду очень признателен тому, кто объяснит почему пример валится в рантайме.

★★

А что будет, если запускать не в IDEA, а из командной строки, как независимый процесс?

Сама-то IDEA поди на 7-ке работает :) ею и запускает твою программу.

BYHYRT
()

Может он не может сам обернуть инты в объекты Integer? У меня нету восьмерки под рукой, но что будет если сделать это вручную? new Integer(1) и new Integer(0) вместо констант.

UPD: и т.к. я уже давно джаву в руках не держал я уже не помню как врапперы с арифметическими операциями взаимодействуют: что будет если ты тупо сложишь два объекта типа Integer.

morse ★★★★★
()
Последнее исправление: morse (всего исправлений: 1)
Ответ на: комментарий от BYHYRT

То же самое, только Launcher другой:

Exception in thread «main» java.lang.VerifyError: Bad return type Exception Details: Location: Test.lambda$main$1(LTest$Function2;Ljava/lang/Integer;)Ljava/lang/Integer; @11: areturn Reason: Type 'java/lang/Object' (current frame, stack[0]) is not assignable to 'java/lang/Integer' (from method signature) Current Frame: bci: @11 flags: { } locals: { 'Test$Function2', 'java/lang/Integer' } stack: { 'java/lang/Object' } Bytecode: 0000000: 2a2b 04b8 0005 b900 0803 00b0

at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2680) at java.lang.Class.getMethod0(Class.java:2929) at java.lang.Class.getMethod(Class.java:1763) at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)

Ian ★★
() автор топика
Ответ на: комментарий от morse

Не помогает. Обернул и константы, и результат сложения.

Он их развернет в маленькие инты.

Ian ★★
() автор топика
Последнее исправление: Ian (всего исправлений: 1)
Ответ на: комментарий от Ian

тяжело стектрейс отформатировать?

Deleted
()

Рабочий вариант

А вот так работает:

public class Test {

    @FunctionalInterface
    public static interface Function1<R, A> {
        R apply(A input);
    }

    @FunctionalInterface
    public static interface Function2<R, A1, A2> {
        R apply(A1 input1, A2 input2);
    }

    public static void main(String[] args) {
        final Function2<Integer, Integer, Integer> add = (x, y) -> x + y;
        final Function1<Integer, Integer> inc = x -> add.apply(x, 1);
        System.out.println(inc.apply(0));
    }

}

Проблема в круглых скобочках.

Ian ★★
() автор топика
Ответ на: Рабочий вариант от Ian

проблема похоже в type erasure генериков, поробуй тоже саомое с круглыми скобками но без параметризованных классов

и судя по тому стектрейсу который ты не осилил отформатировать косяк гдето при поиске метода «apply», хотя надо отладчиком гонять

Deleted
()
Ответ на: комментарий от Deleted

Да, вариант с классами без параметров работает и с круглыми скобками вокруг add.apply.

Вообще похоже на баг в JVM или компиляторе. Негоже валиться с такой ошибкой в runtime.

Ian ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.