condition ? truth : false;
Если условие равно
true
, верните первый параметр. Если условие равноfalse
, верните второй параметр.Он называется Условным оператором и является типом Тройной операции .
По моему скромному мнению 1. Используя vector.add (Набор) вместо vector.addall (Набор). Первое добавляет объект коллекции к вектору, и второй добавляет содержание набора. 2. Хотя не связанный с программированием точно, использованием xml синтаксических анализаторов, которые прибывают из многочисленных источников как xerces, jdom. Доверие различным синтаксическим анализаторам и наличие их банок в пути к классу являются кошмаром.
Другой, на который я хотел бы указать, является (слишком распространенным) диском сделать API универсальными. Используя хорошо разработанный универсальный код прекрасен. Разработка Ваше собственное является сложной. Очень сложный!
Только посмотрели на функциональность сортировки/фильтрации в новом Swing JTable
. Это - полный кошмар. Очевидно, что Вы, вероятно, захотите объединить в цепочку, просачивается реальная жизнь, но я нашел, что это невозможный сделать так, просто не используя сырых данных ввело версию обеспеченных классов.
Необъединенная система типов противоречит объектной идее ориентации. Даже при том, что все не должно быть выделено "куче" объекты, программисту нужно все еще разрешить рассматривать типы примитивов вызывающими методами для них.
универсальная реализация системы типов со стиранием типа ужасна, и отбрасывает большинство студентов, когда они узнают о дженериках для первого в Java: Почему мы должны все еще преобразовать тип, если параметр типа уже предоставляется? Да, они гарантировали прежнюю совместимость, но по довольно глупой стоимости.
Движение сначала, вот то, которое я поймал сегодня. Это имело отношение 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");
}
}
, Очевидно, имена изменились для защиты невинного:)
Хеш по умолчанию недетерминирован, поэтому, если используется для объектов в HashMap, упорядочивание записей в той карте может измениться от выполненного для выполнения.
Как простая демонстрация, следующая программа может дать различные результаты в зависимости от того, как она выполняется:
public static void main(String[] args) {
System.out.println(new Object().hashCode());
}
то, Сколько памяти выделяется "куче", или выполняете ли Вы его в отладчике, может оба изменить результат.
Среди распространенных ошибок, известных, но все еще резких иногда программисты, существует классическое 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, я обновил свой ответ.
(ООН) Упаковка и Длинный/длинный беспорядок. Вопреки предварительному Java 5 опытов можно получить NullPointerException на 2-й строке ниже.
Long msec = getSleepMsec();
Thread.sleep(msec);
, Если getSleepTime () возвращает пустой указатель, распаковывая броски.
если у Вас есть метод, который имеет то же имя как конструктор, НО имеет тип возврата. Хотя этот метод похож на конструктора (новичку), это не.
передающие аргументы основному методу - это занимает время для новичков для привыкания к.
передача. как аргумент пути к классу для того, чтобы выполнить программу в текущем каталоге.
Понимание, что название Массива строк не очевидно
хэш-код и равняется: много Java-разработчиков с опытом больше чем 5 лет не вполне получает его.
Набор по сравнению со Списком
До JDK 6, Java не имел NavigableSets, чтобы позволить Вам легко выполнить итерации через Набор и Карту.
Управление компонентами Swing снаружи потока отправки события может привести к ошибкам, которые чрезвычайно трудно найти. Это - вещь, даже мы (как закаленные программисты с 3 соответствующими 6 годами опыта Java) часто забываем! Иногда эти ошибки крадутся в записав право кода и осуществляющий рефакторинг небрежно впоследствии...
Видят этот учебное руководство , почему Вы должны .
Плавания
я много раз не знаю, что я видел
floata == floatb
, где "корректный" тест должен быть
Math.abs(floata - floatb) < 0.001
, мне действительно жаль, что BigDecimal с литеральным синтаксисом не был десятичным типом по умолчанию...
этот превзошел меня несколько раз, и я услышал, что довольно многие испытали Java devs тратящий впустую много времени.
ClassNotFoundException---Вы знаете, что класс находится в пути к классу, НО Вы не уверены, почему класс НЕ становится загруженным.
На самом деле, этот класс имеет статический блок. Было исключение в статическом блоке, и кто-то съел исключение. они не должны. Они должны бросать ExceptionInInitializerError. Так, всегда ищите статические блоки для смещения Вас. Это также помогает переместить любой код в статические блоки для входа в статические методы так, чтобы отладка метода была намного более легче с отладчиком.
Этот я просто столкнулся:
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 массивов элемента...
List<Integer> list = new java.util.ArrayList<Integer>();
list.add(1);
list.remove(1); // throws...
старые API не были разработаны с упаковкой в памяти, так перегрузка с примитивами и объектами.
Попытайтесь читать Трудные вопросы Java , который полон страшного материала, даже если большая часть его не является материалом, в который Вы врезаетесь каждый день. Но это уничтожит большую часть Вашей уверенности в языке.
Существуют два, которые раздражают меня вполне немного.
Первый, классы Даты и Календаря 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 ()" строки повсеместно. Но те преимущества идут с этим глюком.
SimpleDateFormat не ориентирован на многопотоковое исполнение.
Я думаю, что очень подлый - String.substring
метод. Это снова использует то же лежание в основе char[]
массив как исходная строка с различным offset
и length
.
Это может привести к очень твердым для видения проблемам памяти. Например, можно анализировать чрезвычайно большие файлы (XML
, возможно) для нескольких маленьких битов. Если Вы преобразовали целый файл в String
(а не использовали Reader
для "хождения" по файлу), и использование substring
для захвата битов, Вы хотите, Вы все еще несете вокруг полного размера файла char[]
массив негласно. Я видел, что это происходит неоднократно, и может быть очень трудно определить.
На самом деле это - идеальный пример того, почему интерфейс никогда не может полностью разделяться от [1 110] реализация . И это было идеальное введение (для меня) много лет назад относительно того, почему необходимо с подозрением относиться к качеству стороннего кода.
Переопределение равняется (), но не хэш-код ()
Оно может иметь действительно неожиданные результаты при использовании карт, наборов или списков.
Сравнение равенства объектов с помощью ==
вместо .equals()
- который ведет себя полностью по-другому для примитивов.
Этот глюк гарантирует, что вновь прибывшие удивлены когда "foo" == "foo"
, но new String("foo") != new String("foo")
.
Неизменные строки, что означает, что определенные методы не изменяют исходный объект, но вместо этого возвращают измененную объектную копию. При запуске с Java я раньше забывал это все время и задался вопросом, почему метод замены, казалось, не работал над моим строковым объектом.
String text = "foobar";
text.replace("foo", "super");
System.out.print(text); // still prints "foobar" instead of "superbar"
"a,b,c,d,,,".split(",").length
возвращает 4, не 7, как вы могли (и я, конечно, сделал ) ожидали. split
игнорирует все завершающие возвращенные пустые строки. Это означает:
",,,a,b,c,d".split(",").length
возвращает 7! Чтобы получить то, что я бы назвал «наименее удивительным» поведением, вам нужно сделать что-то весьма удивительное:
"a,b,c,d,,,".split(",",-1).length
, чтобы получить 7.
Я думаю, что у меня большая проблема, которая всегда озадачила меня, когда я был молодым программистом, было исключение одновременной модификации при удалении из массива, который вы выполняли итерации:
List list = new ArrayList();
Iterator it = list.iterator();
while(it.hasNext()){
//some code that does some stuff
list.remove(0); //BOOM!
}
Не совсем специфично для 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
.
Убедитесь, что вы знаете, как оператор %
работает с отрицательными числами,
Когда вы создаете дубликат
или фрагмент
из 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