Java - общие [закрытые] глюки

condition ? truth : false;

Если условие равно true, верните первый параметр. Если условие равно false, верните второй параметр.

Он называется Условным оператором и является типом Тройной операции .

50
задан Community 23 May 2017 в 02:02
поделиться

25 ответов

По моему скромному мнению 1. Используя vector.add (Набор) вместо vector.addall (Набор). Первое добавляет объект коллекции к вектору, и второй добавляет содержание набора. 2. Хотя не связанный с программированием точно, использованием xml синтаксических анализаторов, которые прибывают из многочисленных источников как xerces, jdom. Доверие различным синтаксическим анализаторам и наличие их банок в пути к классу являются кошмаром.

0
ответ дан questzen 7 November 2019 в 10:25
поделиться

Другой, на который я хотел бы указать, является (слишком распространенным) диском сделать API универсальными. Используя хорошо разработанный универсальный код прекрасен. Разработка Ваше собственное является сложной. Очень сложный!

Только посмотрели на функциональность сортировки/фильтрации в новом Swing JTable. Это - полный кошмар. Очевидно, что Вы, вероятно, захотите объединить в цепочку, просачивается реальная жизнь, но я нашел, что это невозможный сделать так, просто не используя сырых данных ввело версию обеспеченных классов.

1
ответ дан oxbow_lakes 7 November 2019 в 10:25
поделиться

Необъединенная система типов противоречит объектной идее ориентации. Даже при том, что все не должно быть выделено "куче" объекты, программисту нужно все еще разрешить рассматривать типы примитивов вызывающими методами для них.

универсальная реализация системы типов со стиранием типа ужасна, и отбрасывает большинство студентов, когда они узнают о дженериках для первого в Java: Почему мы должны все еще преобразовать тип, если параметр типа уже предоставляется? Да, они гарантировали прежнюю совместимость, но по довольно глупой стоимости.

2
ответ дан 7 November 2019 в 10:25
поделиться

Движение сначала, вот то, которое я поймал сегодня. Это имело отношение Long / long беспорядок.

public void foo(Object obj) {
    if (grass.isGreen()) {
        Long id = grass.getId();
        foo(id);
    }
}
private void foo(long id) {
    Lawn lawn = bar.getLawn(id);
    if (lawn == null) {
        throw new IllegalStateException("grass should be associated with a lawn");
    }   
}

, Очевидно, имена изменились для защиты невинного:)

1
ответ дан Alan 7 November 2019 в 10:25
поделиться

Хеш по умолчанию недетерминирован, поэтому, если используется для объектов в HashMap, упорядочивание записей в той карте может измениться от выполненного для выполнения.

Как простая демонстрация, следующая программа может дать различные результаты в зависимости от того, как она выполняется:

public static void main(String[] args) {
    System.out.println(new Object().hashCode());
}

то, Сколько памяти выделяется "куче", или выполняете ли Вы его в отладчике, может оба изменить результат.

4
ответ дан Stephen Denne 7 November 2019 в 10:25
поделиться

Среди распространенных ошибок, известных, но все еще резких иногда программисты, существует классическое if (a = b), который найден всего подобным языкам C.

В Java, это может работать, только если a и b являются булевской переменной, конечно. Но я вижу слишком часто новичков, тестирующих как if (a == true) (в то время как if (a) короче, более читаем и более безопасен...), и иногда пишущий по ошибке if (a = true), задаваясь вопросом, почему тест не работает.
Для тех, которые не получают его: последний оператор сначала присваивается true к a, затем сделайте тест, которые всегда успешно выполняются!

-

Тот, который кусает партию новичков, и даже некоторые отвлекли более опытных программистов (нашел его в нашем коде), if (str == "foo"). Обратите внимание, что я всегда задавался вопросом, почему Sun переопределил +, расписываются за строки, но не == один, по крайней мере, для простых (чувствительных к регистру) случаев.

Для новичков: == сравнивает ссылки, не содержание строк. У Вас может быть две строки того же содержания, сохраненного в различных объектах (различные ссылки), таким образом == будет ложь.

Простой пример:

final String F = "Foo";
String a = F;
String b = F;
assert a == b; // Works! They refer to the same object
String c = "F" + F.substring(1); // Still "Foo"
assert c.equals(a); // Works
assert c == a; // Fails

-

И я также видел if (a == b & c == d) или что-то как этот. Это работает (любопытно), но мы проиграли, ярлык логического оператора (не пытайтесь записать: if (r != null & r.isSomething())!).

Для новичков: при оценке a && b, Java не оценивает b, если ложь. В [1 113], Java оценивает обе части, тогда делают операцию; но вторая часть может перестать работать.

[РЕДАКТИРОВАНИЕ] Хорошее предложение от Ложбин J, я обновил свой ответ.

3
ответ дан PhiLho 7 November 2019 в 10:25
поделиться

(ООН) Упаковка и Длинный/длинный беспорядок. Вопреки предварительному Java 5 опытов можно получить NullPointerException на 2-й строке ниже.

Long msec = getSleepMsec();
Thread.sleep(msec);

, Если getSleepTime () возвращает пустой указатель, распаковывая броски.

4
ответ дан Darron 7 November 2019 в 10:25
поделиться

Целочисленное деление

1/2 == 0 not 0.5
7
ответ дан John Nilsson 7 November 2019 в 10:25
поделиться

если у Вас есть метод, который имеет то же имя как конструктор, НО имеет тип возврата. Хотя этот метод похож на конструктора (новичку), это не.

передающие аргументы основному методу - это занимает время для новичков для привыкания к.

передача. как аргумент пути к классу для того, чтобы выполнить программу в текущем каталоге.

Понимание, что название Массива строк не очевидно

хэш-код и равняется: много Java-разработчиков с опытом больше чем 5 лет не вполне получает его.

Набор по сравнению со Списком

До JDK 6, Java не имел NavigableSets, чтобы позволить Вам легко выполнить итерации через Набор и Карту.

7
ответ дан anjanb 7 November 2019 в 10:25
поделиться

Управление компонентами Swing снаружи потока отправки события может привести к ошибкам, которые чрезвычайно трудно найти. Это - вещь, даже мы (как закаленные программисты с 3 соответствующими 6 годами опыта Java) часто забываем! Иногда эти ошибки крадутся в записав право кода и осуществляющий рефакторинг небрежно впоследствии...

Видят этот учебное руководство , почему Вы должны .

8
ответ дан Daniel Hiller 7 November 2019 в 10:25
поделиться

Плавания

я много раз не знаю, что я видел

floata == floatb

, где "корректный" тест должен быть

Math.abs(floata - floatb) < 0.001

, мне действительно жаль, что BigDecimal с литеральным синтаксисом не был десятичным типом по умолчанию...

16
ответ дан John Nilsson 7 November 2019 в 10:25
поделиться

этот превзошел меня несколько раз, и я услышал, что довольно многие испытали Java devs тратящий впустую много времени.

ClassNotFoundException---Вы знаете, что класс находится в пути к классу, НО Вы не уверены, почему класс НЕ становится загруженным.

На самом деле, этот класс имеет статический блок. Было исключение в статическом блоке, и кто-то съел исключение. они не должны. Они должны бросать ExceptionInInitializerError. Так, всегда ищите статические блоки для смещения Вас. Это также помогает переместить любой код в статические блоки для входа в статические методы так, чтобы отладка метода была намного более легче с отладчиком.

16
ответ дан anjanb 7 November 2019 в 10:25
поделиться

Этот я просто столкнулся:

double[] aList = new double[400];

List l = Arrays.asList(aList);
//do intense stuff with l

Кто-либо видит проблему?

<час>

то, Что происходит, Arrays.asList() ожидает массив типов объектов (Дважды [], например). Было бы хорошо, если бы это просто бросило ошибку для предыдущего ocde. Однако asList() может также взять аргументы как так:

Arrays.asList(1, 9, 4, 4, 20);

Поэтому то, что делает код, создают List с одним элементом - double[].

я должен был изобразить, когда это взяло 0ms для сортировки 750 000 массивов элемента...

17
ответ дан Claudiu 7 November 2019 в 10:25
поделиться
List<Integer> list = new java.util.ArrayList<Integer>();
list.add(1);
list.remove(1); // throws...

старые API не были разработаны с упаковкой в памяти, так перегрузка с примитивами и объектами.

20
ответ дан Tom Hawtin - tackline 7 November 2019 в 10:25
поделиться

Попытайтесь читать Трудные вопросы Java , который полон страшного материала, даже если большая часть его не является материалом, в который Вы врезаетесь каждый день. Но это уничтожит большую часть Вашей уверенности в языке.

21
ответ дан David Plumpton 7 November 2019 в 10:25
поделиться

Существуют два, которые раздражают меня вполне немного.

Дата/Календарь

Первый, классы Даты и Календаря Java серьезно испорчены. Я знаю, что существуют предложения зафиксировать их, я просто надеюсь, что они успешно выполняются.

Calendar.get (Календарь. DAY_OF_MONTH), на основе 1
Calendar.get (Календарь. МЕСЯЦ), на основе 0

предотвращение Автоупаковки, думая

, другой является Целым числом по сравнению с интервалом (это идет для любой примитивной версии объекта). Это - конкретно раздражение, вызванное, не думая о Целом числе как отличающемся от интервала (так как можно рассматривать их то же большая часть времени из-за автоупаковки).

int x = 5;
int y = 5;
Integer z = new Integer(5);
Integer t = new Integer(5);

System.out.println(5 == x);     // Prints true
System.out.println(x == y);     // Prints true
System.out.println(x == z);     // Prints true (auto-boxing can be so nice)
System.out.println(5 == z);     // Prints true
System.out.println(z == t);     // Prints SOMETHING

, Так как z и t являются объектами, даже они, хотя содержат то же значение, они - (наиболее вероятные) различные объекты. То, что Вы действительно имели в виду:

System.out.println(z.equals(t));   // Prints true

Этот может быть болью для разыскивания. Вы идете, отлаживая что-то, все выглядит хорошо, и Вы наконец заканчиваете тем, что нашли, что Ваша проблема - это 5! = 5, когда оба - объекты.

Способность сказать

List<Integer> stuff = new ArrayList<Integer>();

stuff.add(5);

так хороша. Это сделало Java настолько более применимым для не помещения весь те "новое Целое число (5) "s и" ((Целое число) list.get (3)) .intValue ()" строки повсеместно. Но те преимущества идут с этим глюком.

21
ответ дан Joey 7 November 2019 в 10:25
поделиться

SimpleDateFormat не ориентирован на многопотоковое исполнение.

25
ответ дан 7 November 2019 в 10:25
поделиться

Я думаю, что очень подлый - String.substring метод. Это снова использует то же лежание в основе char[] массив как исходная строка с различным offset и length.

Это может привести к очень твердым для видения проблемам памяти. Например, можно анализировать чрезвычайно большие файлы (XML, возможно) для нескольких маленьких битов. Если Вы преобразовали целый файл в String (а не использовали Reader для "хождения" по файлу), и использование substring для захвата битов, Вы хотите, Вы все еще несете вокруг полного размера файла char[] массив негласно. Я видел, что это происходит неоднократно, и может быть очень трудно определить.

На самом деле это - идеальный пример того, почему интерфейс никогда не может полностью разделяться от [1 110] реализация . И это было идеальное введение (для меня) много лет назад относительно того, почему необходимо с подозрением относиться к качеству стороннего кода.

30
ответ дан oxbow_lakes 7 November 2019 в 10:25
поделиться

Переопределение равняется (), но не хэш-код ()

Оно может иметь действительно неожиданные результаты при использовании карт, наборов или списков.

30
ответ дан extraneon 7 November 2019 в 10:25
поделиться

Сравнение равенства объектов с помощью == вместо .equals() - который ведет себя полностью по-другому для примитивов.

Этот глюк гарантирует, что вновь прибывшие удивлены когда "foo" == "foo", но new String("foo") != new String("foo").

35
ответ дан David 7 November 2019 в 10:25
поделиться

Неизменные строки, что означает, что определенные методы не изменяют исходный объект, но вместо этого возвращают измененную объектную копию. При запуске с Java я раньше забывал это все время и задался вопросом, почему метод замены, казалось, не работал над моим строковым объектом.

String text = "foobar";
text.replace("foo", "super");
System.out.print(text); // still prints "foobar" instead of "superbar"
8
ответ дан riadd 7 November 2019 в 10:25
поделиться
"a,b,c,d,,,".split(",").length

возвращает 4, не 7, как вы могли (и я, конечно, сделал ) ожидали. split игнорирует все завершающие возвращенные пустые строки. Это означает:

",,,a,b,c,d".split(",").length

возвращает 7! Чтобы получить то, что я бы назвал «наименее удивительным» поведением, вам нужно сделать что-то весьма удивительное:

"a,b,c,d,,,".split(",",-1).length

, чтобы получить 7.

36
ответ дан 7 November 2019 в 10:25
поделиться

Я думаю, что у меня большая проблема, которая всегда озадачила меня, когда я был молодым программистом, было исключение одновременной модификации при удалении из массива, который вы выполняли итерации:

  List list = new ArrayList();
    Iterator it = list.iterator();
    while(it.hasNext()){
      //some code that does some stuff
      list.remove(0); //BOOM!
  }
8
ответ дан 7 November 2019 в 10:25
поделиться

Не совсем специфично для Java, поскольку многие (но не все) языки реализуют это таким образом, но оператор % не является истинным оператором по модулю, поскольку он работает с отрицательными числами. Это делает его оператором остатка и может привести к некоторым сюрпризам, если вы этого не знаете.

Следующий код может выводить либо «четный», либо «нечетный», но это не так. t.

public static void main(String[] args)
{
    String a = null;
    int n = "number".hashCode();

    switch( n % 2 ) {
        case 0:
            a = "even";
            break;
        case 1:
            a = "odd";
            break;
    }

    System.out.println( a );
}

Проблема в том, что хэш-код для «числа» отрицательный, поэтому операция n% 2 в коммутаторе также отрицательна. Поскольку в переключателе нет случая, чтобы иметь дело с отрицательным результатом, переменная a никогда не устанавливается. Программа выводит null .

Убедитесь, что вы знаете, как оператор % работает с отрицательными числами,

13
ответ дан 7 November 2019 в 10:25
поделиться

Когда вы создаете дубликат или фрагмент из ByteBuffer , он не наследует значение свойства order из родительского буфера, поэтому такой код не будет делать то, что вы ожидаете:

ByteBuffer buffer1 = ByteBuffer.allocate(8);
buffer1.order(ByteOrder.LITTLE_ENDIAN);
buffer1.putInt(2, 1234);

ByteBuffer buffer2 = buffer1.duplicate();
System.out.println(buffer2.getInt(2));
// Output is "-771489792", not "1234" as expected
4
ответ дан 7 November 2019 в 10:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: