Некоторые из самых странных 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 48 ch *= 1.1 ; // 48 x 1.1 is 52.8 which turns to 52 when cast to char System.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 . |