Логический вывод типа в Java8

1

Я хотел бы знать, почему код ☆2 можно скомпилировать с помощью Java8:

public class Sandbox {

    public static void main(String[] args) {

        // ☆1: NG: Type mismatch: cannot convert from Object to String
        String res0 = IList.nil().head(); 

        // ☆2: OK: I don't know why it OK.
        String res1 = IList.nil().head2();
    }

    static class IList<E> {

        static <Z> IList<Z> nil() {
            return null;
        }

        E head() {
            return null;
        }

        <TeE extends E> TeE head2() {
            return null;
        }
    }
}

Примечание. Также мне интересно, что цель JEP (http://openjdk.java.net/jeps/101).

Теги:
generics
java-8

2 ответа

4
Лучший ответ

Обычно Java по умолчанию использует generics для своей внешней границы. В этом конкретном случае он

 String res1 = IList.<Object>nil().<String>head2();

... потому что только внешний метод вызывает "знает" желаемый тип результата.

  • 0
    Это изменение Java 8?
  • 0
    Не на самом деле нет.
Показать ещё 6 комментариев
4

Это не имеет ничего общего с Java 8. # 2 также компилируется на Java 7.

Я думаю, что все это сводится к тому, что <TeE extends E> в вашем методе head2. Java видит, что вы ожидаете String в ответ, из-за этой строки:

String res1 = IList.nil().head2();

Поэтому делается вывод, что, ах, в этом случае я буду возвращать String сейчас - потому что String расширяет Object, поэтому <TeE extends E> является действительным.

Это работает благодаря тому, что вы возвращаете значение null внутри метода. Если вы этого не сделаете, в этом методе возникнет ошибка. И поскольку значение null может быть присвоено всем, кроме примитивов, этот код в порядке.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню