$ cat Main.java
public class Main {
public static void main(String ... args) {
var person = new Object() {
String name = "bob";
int age = 5;
};
System.out.println(person.name + " aged " + person.age);
}
}
$ ../jdk-10/bin/javac Main.java
$ ../jdk-10/bin/java Main
bob aged 5
Есть ещё один интересный тип: catch (Exception1 | Exception2 e). Если проявить воображение, эту фичу наверняка можно заабузить для чего-нибудь прикольного
Здравствуйте, vsb, Вы писали:
vsb>Есть ещё один интересный тип: catch (Exception1 | Exception2 e). Если проявить воображение, эту фичу наверняка можно заабузить для чего-нибудь прикольного
Насколько я понимаю, никакого интересного типа тут нет — "e" получает тип ближайшего общего предка. Соответственно, к уникальным полям/методам Exception1/2 ты доступа не имеешь (без явного каста)
Здравствуйте, serb, Вы писали:
S>Здравствуйте, bzig, Вы писали:
S>Из этого вытекает другая фича, невозможно переприсвоение таких переменных.
S> var person = new Object() {}; S> person = new Object() {}; // Compile ERROR S>переменной person нельзя присвоить другой Object.
Ну так и правильно — ты неявно создал два анонимных класса и они не присваиваются друг другу.
Здравствуйте, bzig, Вы писали:
B>Здравствуйте, serb, Вы писали:
S>>Здравствуйте, bzig, Вы писали:
S>>Из этого вытекает другая фича, невозможно переприсвоение таких переменных.
S>> var person = new Object() {}; S>> person = new Object() {}; // Compile ERROR S>>переменной person нельзя присвоить другой Object.
B>Ну так и правильно — ты неявно создал два анонимных класса и они не присваиваются друг другу.
Не просто анонимные классы, а классы, расширяющие Object. Если бы слева был Object, то все ok. Другое дело имеет ли это смысл. Например, присваивать разные реализации одного и того же интерфейса какой-то переменной в методе класса-фабрики с целью ее инициализации и возвращения наверх.
"Не волнуйся, голова! Теперь будет думать компьютер"
Гомер Джей Симпсон
B>>Ну так и правильно — ты неявно создал два анонимных класса и они не присваиваются друг другу.
UDI>Не просто анонимные классы, а классы, расширяющие Object. Если бы слева был Object, то все ok.
Открою тебе секрет — анонимные классы по определению расширяют какой-то класс. Ну и чтобы два раза не вставать — все классы в Яве расширяют Object
B>>>Ну так и правильно — ты неявно создал два анонимных класса и они не присваиваются друг другу.
UDI>>Не просто анонимные классы, а классы, расширяющие Object. Если бы слева был Object, то все ok.
B>Открою тебе секрет — анонимные классы по определению расширяют какой-то класс. Ну и чтобы два раза не вставать — все классы в Яве расширяют Object
Ok, так. Все расширяют, но не все экземпляры это экземпляры нужных тебе классов, т.е. то о чем по-моему serb тебе говорил, что теперь "неявность" вроде var приводит напротив к абсолютно явному определению типа, хотя и неявномсу для самого разработчика. И то самое "переприсваивание" в такой записи невозможно.
"Не волнуйся, голова! Теперь будет думать компьютер"
Гомер Джей Симпсон
UDI>И то самое "переприсваивание" в такой записи невозможно.
Да, поэтому полноценных туплов всё ещё нет. С другой стороны кое-какое присваивание всё-таки возможно. Например, если в потоке насоздавал объектов некоего "невозможного" типа и собрал в коллекцию, то потом можно этими объектами манипулировать: менять местами в коллекции, присваивать элементы коллекции переменным и потом манипулировать этими переменными, в том числе и переприсваивать. Главное, чтобы определение анонимного класса было в одном месте только (у серба было в двух).
B> С другой стороны кое-какое присваивание всё-таки возможно.
$ cat Main.java
public class Main {
public static void main(String ... args) {
var list = java.util.stream.Stream.of("Bob","Alice")
.map(s -> new Object() {
String name = s;
int age = 5;
})
.collect(java.util.stream.Collectors.toList());
var first = list.get(0);
var second = list.get(1);
System.out.println("first is "+first.name + ", second is " + second.name);
var swap = first;
first = second;
second = swap;
System.out.println("first is "+first.name + ", second is " + second.name);
}
}
$ ../jdk-10/bin/javac Main.java
$ ../jdk-10/bin/java Main
first is Bob, second is Alice
first is Alice, second is Bob
B>> С другой стороны кое-какое присваивание всё-таки возможно.
B>
B> var list = java.util.stream.Stream.of("Bob","Alice")
B> .map(s -> new Object() {
B> String name = s;
B> int age = 5;
B> })
B> .collect(java.util.stream.Collectors.toList());
B>
Да, так получается. Но тут в функции отражения (map) создается лишь один анонимный класс AC1 (точнее создается он при компиляции) и затем используется столько экземпляров AC1, сколько нужно для преобразования потока данных. Получается список экземпляров AC1. И везде за var скрывается AC1.
В общем, как по мне, так это еще один "сахарок", интересный, и применять его надо к месту. К сожалению, скорее всего использовать его будут везде-везде и это будет приводить к казусам и неочевидностям.
"Не волнуйся, голова! Теперь будет думать компьютер"
Гомер Джей Симпсон
Как раз не сахарок. Вместо var тут ничего нельзя поставить, чтобы работало. Только создавать настоящий класс. Т.е. этот var превратил impossible type в possible
Здравствуйте, vsb, Вы писали:
vsb>Есть ещё один интересный тип: catch (Exception1 | Exception2 e). Если проявить воображение, эту фичу наверняка можно заабузить для чего-нибудь прикольного