Какой самый вводящий в заблуждение метод в Java Base API?
Недавно я пытался преобразовать строковый литерал в boolean
, когда метод boolean Boolean.getBoolean(String name)
выскочил из автозаполнения окно. Был также другой метод (boolean Boolean.parseBoolean(String s)
), появившийся сразу после этого, что привело меня к поиску, чтобы выяснить, каковы различия между этими двумя, поскольку они оба, похоже, делали то же самое.
Оказывается, что то, что Boolean.getBoolean(String name)
действительно делает, это проверить, существует ли свойство > (!) данного имени и если его значение true
. Я думаю, что это очень вводит в заблуждение, поскольку я определенно не ожидаю, что метод boolean
действительно вызывает вызов System.getProperty
, и просто взглянув на подпись метода, он уверен, что выглядит (по крайней мере для меня), как будто он должен использоваться для анализа String
как boolean
. Конечно, javadoc четко заявляет, но я все же считаю, что метод имеет вводящее в заблуждение имя, и это не в нужном месте. Другие примитивные обертки типа, такие как Integer
, также имеют аналогичный метод.
Кроме того, это не очень полезный метод, который должен принадлежать базовому API, так как я думаю, что это не очень похоже на нечто вроде -Darg=true
. Может быть, это хороший вопрос для интервью на Java: "Что такое вывод Boolean.getBoolean("true")
?". Я считаю, что более подходящее место для этих методов будет в классе System
, например, getPropertyAsBoolean
; но опять же, я по-прежнему считаю ненужным использовать эти методы в базовом API. Было бы разумно иметь их в чем-то вроде класса Properties
, где очень часто делается этот тип преобразований.
Что вы думаете обо всем этом? Кроме того, если есть другой "неудобный" метод, о котором вы знаете, отправьте его.
N.B. Я знаю, что я могу использовать Boolean.valueOf
или Boolean.parseBoolean
для преобразования строкового литерала в boolean
, но я просто хочу обсудить дизайн API.
Ответы
Ответ 1
Метод URL equals() сравнивает IP-адреса, использует сетевое соединение и является блокировкой!
Из javadocs:
Два хоста считаются эквивалентными, если оба имени хоста могут быть решены в те же IP-адреса; иначе если имя хоста не может быть разрешено, имена хостов должны быть равны независимо от случая; или оба имена хостов равны нулю.
Так как для сравнения хостов требуется разрешение имен, эта операция является блокировка.
Примечание. Определенное поведение для равных значений известно быть несовместимым с виртуальным хостингом в HTTP.
Вместо этого используйте URI.
Ответ 2
Одна известная проблема с классом Calendar состоит в том, что месяцы нумеруются от 0 до 11 вместо 1 до 12. Очень легко сделать ошибку следующим образом:
Calendar cal = Calendar.getInstance();
// Set date to August 18, 2009? WRONG! Sets the date to September 18, 2009!
cal.set(2009, 8, 18);
Правильный способ сделать это - использовать константы в течение месяцев:
cal.set(2009, Calendar.AUGUST, 18);
Но метод делает слишком легко совершить ошибку при использовании нормальных чисел месяца от 1 до 12.
Я рассматриваю это как ошибку в дизайне класса Calendar.
Ответ 3
Просто получил этот здесь, касающийся методов add
и remove
List
(при параметризации с помощью Integer
). Например:
List<Integer> l = new ArrayList<Integer>();
l.add(20);
l.remove(20); // throws ArrayIndexOutOfBoundsException, because it will try to access index 20
l.remove(new Integer(20)); // this works
Ответ 4
String.getBytes()
часто является причиной множества глупых проблем кодирования символов в приложениях, потому что он использует кодировку символов базовой платформы.
Ответ 5
Просто узнал о методах isInterrupted
и interrupted
класса Thread
. Из javadoc
:
static boolean interrupted()
// Tests whether the current thread has been interrupted.
boolean isInterrupted()
// Tests whether this thread has been interrupted.
Проблема заключается в том, что interrupted
фактически очищает прерванный статус, помимо выполнения теста, а isInterrupted
просто проверяет состояние.
Ответ 6
Вероятно, это не самый худший метод, но мне никогда не нравилось этот:
Предположим, что x - это список, который, как известно, содержит только строки. Следующий код можно использовать для удаления списка в новый выделенный массив String:
String[] y = x.toArray(new String[0]);
Передача массива String размера 0 в метод просто кажется сумасшедшим и неинтуитивным для меня.
Ответ 7
InputStream.read(byte [])
Не заполняет массив; вместо этого он считывает произвольное количество байтов и возвращает это число. Вы должны зациклиться. Отвратительно, потому что он работает правильно для небольших массивов большую часть времени. Я не думаю, что кто-то правильно это понимает в первый раз, когда они его используют.
Ответ 8
Некоторые redditor заметили, что String.substring приводит к утечкам памяти, потому что внутри он не копирует подстроку, а просто копирует указатель на целую строку + смещение + длину. Поэтому, если вы ожидаете, что вся строка будет собрана GC, вы будете ввернуты.
http://www.reddit.com/r/programming/comments/8ydvg/the_dangers_of_stringsubstring/c0au0gj
Ответ 9
моя проблема связана с методом подстроки String; каждый раз, когда я его использую, я должен написать слово "гамбургер" и "гамбургер".substring(4,8) = "побуждать" запомнить, как правильно его использовать.
Ответ 10
Ну, System.setOut() установит значение в final члена System!!!!
Ответ 11
Я никогда не понимал, почему API JDBC последовательно начинает подсчет с 1, тогда как остальные юниверсы Java (и C, С++, С#,...) начинаются с 0. Это относится к номерам столбцов, номерам параметров в подготовленном заявления и т.д.
Ответ 12
Я согласен. Мне всегда было неудобно с этими методами.
Я даже обнаружил ошибку в нашей базе кода, которая была вызвана кем-то, использующим Integer.getInteger() для синтаксического анализа строки, не понимая, что она ищет свойство.
К сожалению, конечно, API API не может быть удален из-за соображений обратной совместимости.
Ответ 13
Я не уверен, что кто-то все еще использует это, но сообщение об ошибке из DocumentBuilder.parse()
, если что-то пойдет не так, (почти?) всегда "Содержимое не допускается в прологе". даже если реальная причина была чем-то другим.
Ответ 14
BigDecimal.setScale(int) сеттер, который возвращает BigDecimal hmmm
Ответ 15
Одно из моих любимых мотивов с Java - это тот факт, что сбой в Integer.parseInt( "SomeString" ) просто указывает, что произошла ошибка синтаксического анализа, не сказав нам, что такое "SomeString".
Из-за этого иногда приходится выполнять множество отладки, чтобы узнать, что такое строка. Если ошибка mesage включала ошибочную строку, отслеживание проблемы было бы намного быстрее.
Ответ 16
Я бы не записал его под "Most Awkward", но java.security.MessageDigest.getInstance() дал мне некоторую путаницу.
Обычно я использую метод getInstance(), возвращающий Singleton.
Если метод возвращает новый экземпляр, я могу ожидать увидеть MessageDigestFactory.newInstance() или, по крайней мере, newInstance() в классе MessageDigest вместо метода getInstance().
Смотрите: MessageDigest.getInstance()
Из того, что я тестировал, MessageDigest.getInstance() возвращает новый экземпляр, каждый раз, когда он вызывается.
Ответ 17
java.util.Date.getDate()
возвращено число, 1-31. getDayOfMonth()
- это точный способ объяснить это, в то время как вы обычно пытались запомнить getTime()
.
Не могу дождаться, когда наступит время Джоды.