Некоторые из самых странных Java-головоломок, которые мы получили в свои руки
Даже самые опытные разработчики Java сочтут вопросы в этом посте запутанными. Или, по крайней мере, забавно (и совершенно несправедливо). После нашего приключения с Java Deathmatch мы решили опубликовать на этот раз другой набор вопросов, подчеркивая некоторые необычные и причудливые вещи, которые вы можете сделать с Java. С результатами наших предыдущих викторин вы можете ознакомиться с этим постом и посмотреть, сможете ли вы решить вопрос о том, что 4 из 5 разработчиков ошиблись. 
Попробуйте это дома (или в офисе). Но, пожалуйста, не используйте его в реальных приложениях Java! Если вы не пытаетесь кого-то троллить и в этом случае все идет. Огромная огромная благодарность Питеру Лори за то, что он поделился с нами большинством этих вопросов. Решения доступны в нижней части этого поста, но попробуйте дать им честную попытку и посмотреть, сколько из них вам удастся объяснить.
И вопросы …
1. Закрывающие скобки переоценены
Как ни странно, следующий фрагмент кода прекрасно компилируется. Но что это печатает?
|
1
2
3
4
5
6
7
8
9
|
import static java.lang.Character.getNumericValue;public class BigCharacters { public static void main(String... a) { for (char c = 1; c > 0; c++) if (getNumericValue(c) > 50) System.out.println(c + ": " + getNumericValue(c)); }} |
Примечание: getNumbericValue возвращает числовое значение типа int, которое представляет символ Unicode. Если символ не имеет числового значения, возвращается -1.
2. Ответ на жизнь, вселенную и все
Уф. У нас есть закрывающие скобки на этот раз. Но что распечатывает следующий фрагмент кода? И почему?
|
1
2
3
4
5
6
|
Integer a = 42;Integer b = 42;System.out.println(a == b);Integer c = 666;Integer d = 666;System.out.println(c == d); |
3. Символ арифметики
Двигаемся дальше. Можете ли вы объяснить, что здесь происходит?
|
1
2
3
|
char ch = '0';ch *= 1.1;System.out.println(ch); |
Возможные варианты:
- Ошибка компилятора
- Ошибка выполнения
- Отпечатки 0
- Prints 4
4. Не сдавайся!
Этот только что из этого мира. Что тут происходит?
|
1
2
3
4
|
String _ = "Hello ";String _ = "World";String _ = " !!";System.out.println(_+_+_); |
Оповещение о спойлере: печатается «Hello World !!»
¯ \ _ (ツ) _ / ¯
5. Этот вопрос самоосознан
Какое наименьшее значение печатает WTF? Тип х зависит от вас.
|
1
2
|
if (x != (x += 0.0f)) System.out.println("WTF"); |
Решения
1. Закрывающие скобки переоценены
Сначала немного предыстории. Есть символ, закодированный с \ u202e, который используется для языков справа налево, таких как иврит или арабский, и заставляет остальную часть строки отображаться в обратном порядке. Это символ нулевой ширины, и не только, он также допустим для использования в качестве идентификатора Java. Попробуйте скопировать фрагмент кода, переместите курсор, и вы увидите, где он появляется в коде.
Помимо поддержки языка RTL, это также очень полезно, если вы хотите разыграть кого-то. Замените закрывающую скобку открывающей скобкой, за которой стоит этот символ, чтобы перевернуть остальную часть строки — и посмотрите, что будет дальше. Если вы решите сделать это, пожалуйста, пришлите нам фотографию лица жертвы. ?
2. Ответ на жизнь, вселенную и все
Целые числа, конечно, являются объектами, в отличие от типа int, который является примитивным типом. Тем не менее, этот фрагмент кода:
|
1
2
3
4
5
6
|
Integer a = 42;Integer b = 42;System.out.println(a == b);Integer c = 666;Integer d = 666;System.out.println(c == d); |
Выводит «true» для первого сравнения и «false» для следующего. Это не сработает для целых чисел, но поскольку целые числа являются отдельными объектами, имеет смысл, что c и d — это не одно и то же. Но почему а == б?
Тип Integer хранит кэш всех объектов со значением в диапазоне от -128 до 127 по соображениям производительности. Поэтому, когда вы объявляете новые переменные в этом диапазоне, вы фактически ссылаетесь на один и тот же объект.
3. Символ арифметики
Этот фрагмент кода печатает 4:
|
1
2
3
|
char ch = '0'; // ASCII for ‘0’ is 48ch *= 1.1; // 48 x 1.1 is 52.8 which turns to 52 when cast to charSystem.out.println(ch); // 52 represents ‘4’ in ASCII |
4. Не сдавайся!
Почему _, _ и _ являются разными переменными? Возможно, вы догадались, это правильно. Ответ со скрытыми символами, которые передаются как законные идентификаторы Java. Вы можете прочитать больше об этом в блоге Питера Лори прямо здесь .
5. Этот вопрос самоосознан
Так что же делает это выражение верным?
|
1
2
|
if (x != (x += 0.0f)) System.out.println("WTF"); |
Вы можете использовать любую String, а также int или long (1 << 24) + 1 работают для этих типов как их наименьшее значение. Но наименьшее значение из них — Double.MIN_VALUE, который округляется до 0.0f при приведении к плавающей точке.
Последние мысли
Мы надеемся, что вам понравилась эта коллекция вопросов! Однако, если вы обнаружите, что тратите слишком много времени на головоломки в своей собственной кодовой базе, это, вероятно, будет далеко не идеальным. Для таких ситуаций мы создали Takipi для Java . Takipi — это Java-агент, который собирает все данные, необходимые для устранения ошибок в работе — БЕЗ просмотра файлов журналов и попытки воссоздать состояние, которое их вызвало. Он позволяет вам видеть значения переменных, которые вызывают ошибки, по всему стеку и накладывать их на ваш код.
| Ссылка: | 5 странных вопросов по Java, которые заставят вас раскрутиться от нашего партнера JCG Алекса Житницкого в блоге Takipi . |

