Готовлюсь к сертификационному экзамену по 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... )
И соответственно тебе без ошибки выдаёт 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
Reply
Попробуйте вместо 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
Т.е.
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
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, if either operand is of type long, the other is converted to long.
Otherwise, both operands are converted to type int.
Binary numeric promotion is performed on the operands of certain operators:
The multiplicative operators *, / and % (§15.17)
The addition and subtraction operators for numeric types + and - (§15.18.2)
The numerical comparison operators <, <=, >, and >= (§15.20.1)
The numerical equality operators == and != (§15.21.1)
The integer bitwise operators &, ^, and | (§15.22.1)
In certain cases, the conditional operator ? : (§15.25)
https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2
Reply
Reply
Reply
String string1 = "hello";
String string2 = "hello";
, то string1==string2 вернет true.
А если
String string1 = new String("hello");
String string2 =new String("hello");
, то false
Reply
На практике времени на вылавливание ошибок вылазящих из-за неявного пребразования типов тратится значительно больше, чем при отлове чисто алгоритмических/логических багов. Соотвественно продуктивность повышать логичнее всего именно дрессируя на подобную хрень .. чтобы обходить такие засады и не тратить на их отлов кучу времени и нервов единственный способ - "просто знать".
Reply
Reply
Ну дело в любом алго-языке в балансе избыточности (которая нужна для приближенности к человеческим языкам и по легкости понимания) и однозначности трансляции. В детской загадке "сколько будет два плюс два умножить на два" всегда найдутся те, кто имплицитно "видит" скобки и получает 8 и кто их "не видит" и получает 6😃 Тут то вопромы не к тем кто язык пооектировал концептуально, поскольку они о таких деталях не думают , а скорее к тем, кто транслятор пишет и кому скорее всего разрешение подобных коллизий отдано на откуп. Архитектор может мыслить сколь угодно стройно и красиво, но вопрос, как именно завести вот эту самую трубу на месте решает прораб на своем уровне компетентности и зарплаты, т.е мотивации в конечном результате 😃
Reply
Reply
Reply
Reply
Reply
Leave a comment