Странный синтаксис приведения Java с использованием & [дубликата]

(На самом деле этот вопрос напрямую связан не с лямбдами, а с приведением типов с использованием границ, поэтому вопрос, помеченный как дубликат, не дает ответа на этот вопрос. Вы найдете ответ на мой вопрос здесь: Как я должен использовать для общего Java с несколькими границами?)

Совсем недавно я принимал участие в собрании мастеров SW. В одном из обсуждаемых примеров я столкнулся с таким приведением, похоже, это действующая Java начиная с Java 8.

Object aTest = (String & CharSequence) "test";

Мой вопрос: может ли кто-нибудь сказать мне идиому, стоящую за этим, и что именно это может сделать для нас? Ведущий примера не смог это объяснить, и я не нашел упоминания (я даже не знаю его названия).

Я должен поместить здесь еще один ответ, в дополнение к ответу Александра, потому что этот вопрос уже был помечен как дубликат и поэтому заблокирован.

Тем временем я смог построить (надуманный) вариант использования, просто чтобы прояснить идею.

Предположим, у нас есть универсальный метод foo(), который является универсальным для своего единственного параметра, а параметр типа имеет две верхние границы (по сравнению с Comparable и Serializable):

public static <T extends Comparable & Serializable> void foo(T t) {
    System.out.println(t);
}

Далее предположим, что у нас есть класс AClass, который реализует Comparable и Serializable.

public class AClass implements Comparable, Serializable {
    @Override
    public int compareTo(Object other) {
        return 0;
    }
}

Далее предположим надуманную часть, где у нас есть AClass объект instance, который присваивается переменной типа Object:

Object instance = new AClass();

Если в другом месте кода мы хотим передать instance в foo() и нам неизвестен динамический тип instance (то есть AClass), мы можем использовать специальный синтаксис приведения, чтобы поместить «контактную линзу» на instance чтобы звонок работал:

foo((Comparable & Serializable) instance);

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


person Nico    schedule 27.06.2018    source источник
comment
Java поддерживает несколько границ для параметры типа.   -  person Elliott Frisch    schedule 27.06.2018
comment
Да, я знаю & по границам типов, но здесь не задействован параметр типа.   -  person Nico    schedule 27.06.2018
comment
Собственно, именно это здесь и происходит. Это в основном полезно с лямбда-нотацией ->.   -  person Elliott Frisch    schedule 27.06.2018
comment
Эллиотт, можешь привести пример?   -  person Nico    schedule 27.06.2018
comment
stackoverflow.com/a/14469627/2970947   -  person Elliott Frisch    schedule 27.06.2018
comment
SortedSet<String> set = new TreeSet<>((Comparator<String> & Serializable) (a, b) -> a.length() - b.length());: без приведения TreeSet не будет сериализуем, потому что его компаратор не будет.   -  person JB Nizet    schedule 27.06.2018


Ответы (1)


Это оператор приведения который может содержать список типов:

(ReferenceType {AdditionalBound}) Expression  =>  (String & CharSequence) "test";

Где AdditionalBound определяется как:

... & InterfaceType

Я понимаю это в целом, но как насчет варианта использования?

Этот вопрос и ответы описывают реальный практический вариант использования. Например, чтобы сделать лямбда-выражение сериализуемым, вы можете написать:

Consumer<String> consumer = (Consumer<String> & Serializable) System.out::println;

(спасибо @assylias)

person Oleksandr Pyrohov    schedule 27.06.2018