Немножко о безумии языка Java

Nov 03, 2020 10:31

Готовлюсь к сертификационному экзамену по Java (OCA, 1Z0-808), с трудом прохожу тесты Enthuware. Вот уже неделю волосы стоят дыбом и не опускаются от вопроса - что же курили создатели?

Образец кода:

public class TestClass {
public static void main(String[] args){
byte b = 127;
System.out.println((b+=1)+" "+((Object)b).getClass());
byte a = 127;
Read more... )

информатика

Leave a comment

Comments 22

natpy November 3 2020, 11:45:45 UTC
Ну a = a+1 не компилируется понятно почему, у тебя результат вычисления действительно вываливается из байта и джава сохраняется его в integer. А затем ты пытаешься присвоить integer в byte.

И соответственно тебе без ошибки выдаёт System.out.println((a+1)+" "+((Object)(a+1)).getClass()); ты ведь результат вычисления a+1 не пытаешься ничему присвоить, сразу выводишь на печать

А вот результат операции += меня удивил. Оказывается он автоматически кастит к нужному типу. То есть a+=1 не эквивалетно a=a+1, а эквивалетно a = (byte)(a+1) возможно я даже знал это когда то, но забыл

На самом деле такого безумия в джаве много

Например Integer.valueOf(127) == Integer.valueOf(127) тебе вернёт true, а Integer.valueOf(128) == Integer.valueOf(128) вернёт false. Выглядит нелепо, а по факту для значений меньше 128 Integer.valueOf не создёт постоянно новые объекты а берёт их из кеша если это возможно.

Но если честно, на практике вся эта ересь никогда почти не встречается. Не понимаю почему ею так любят мучить людей на собеседованиях.

Reply

eternele November 3 2020, 12:23:44 UTC
Нет, не поэтому а=а+1 не компилируется. Если я инициализирую а любым другим числом, результат такой же. На самом деле, при любой математической операции short, byte и, кажется, char превращаются в int. А += считается не математической операцией, а operator overloading, и у него другие правила.

Reply

morfizm November 3 2020, 20:19:09 UTC
Уверен, что это только кажется, а на самом деле причина в том, что численный literal "1" имеет по умолчанию тип int.

Попробуйте вместо 1 использовать переменную "c", которую вы заранее объявили как byte и присвоили туда 1. Если оба операнда имеют тип byte, то и сложение a = a + c будет происходит в рамках byte, не будет расширения диапазона. И просто standalone выражение a + c будет byte.

В Джаве есть трюки, чтобы сказать, что числовая константа имеет тип long (напр., 123L), но нет ни единого трюка, чтобы сказать, что она byte. Надо брать интовое число и down-cast'ить. Видимо, это редко кому надо, поэтому так сделано. Если вместо 1 вы напишете ((byte)1), то будут вам байты без выхода в инты.

https://stackoverflow.com/questions/5193883/how-do-you-specify-a-byte-literal-in-java

Reply

morfizm November 3 2020, 20:26:33 UTC
По ходу, вы были правы в том, что у byte нет своего +, используется интовый и upcast'ит оба операнда.

Т.е.
byte a = 127
byte c = 1
System.out.println((a+c)+" "+((Object)(a+c)).getClass());

Печатает
128 class java.lang.Integer

А вот:
byte a = 127;
byte c = 1;
System.out.println(((byte)(a+c))+" "+((Object)((byte)(a+c))).getClass());

Печатает
-128 class java.lang.Byte

В общем, тип Byte он только для хранения, арифметики у него своей нет.

Reply


natpy November 3 2020, 15:24:43 UTC
Ну и со стрингом понятно "hello" создаст новый объект или возьмет уже имеющийся, а new String явным образом создаст новый объект.

Reply


morfizm November 3 2020, 20:08:24 UTC
Я не вижу тут ничего нелогичного, совершенно очевидные результаты ( ... )

Reply

eternele November 3 2020, 20:58:38 UTC
Если я напишу (byte)1, результат абсолютно такой же. Так что не надо на физиков бочку катить.

Reply


morfizm November 3 2020, 20:21:40 UTC
Отдельно добавлю, на мой взгляд всё строго и чётко. Это у физиков дурдом с тем, что они не указывают типы и размерности, и всё у них работает по принципу "догадайся, что тут должно быть по смыслу", без явного прописывания.

Reply

eternele November 3 2020, 20:59:27 UTC
В том-то и дело, что в Яве один раз работает по одному принципу, другой раз по-другому.

Reply

morfizm November 3 2020, 21:00:28 UTC
Я думаю, Джава просто обижается, что вы её называете Явой, и мстит вам за это ;)

Reply

eternele November 4 2020, 06:45:21 UTC
Later the project went by the name Green and was finally renamed Java, from Java coffee, the coffee from Indonesia.

Я́ва (индон. и яв. Jawa) - остров в составе Индонезии (столица Индонезии, Джакарта, расположена на этом острове)

Reply


Leave a comment

Up