Ответ 1
Мне пришлось поддерживать Java-код, где большая часть обработки Исключения была похожа:
catch( Exception e ) {}
Как этот вопрос...
Каковы худшие практики, которые вы действительно нашли в Java-коде?
Мои:
Мне пришлось поддерживать Java-код, где большая часть обработки Исключения была похожа:
catch( Exception e ) {}
Как только я столкнулся с исключением "singleton":
class Singletons {
public static final MyException myException = new MyException();
}
class Test {
public void doSomething() throws MyException {
throw Singletons.myException;
}
}
Тот же экземпляр исключения каждый раз бросался... с точно такой же stacktrace, которая не имела никакого отношения к реальному потоку кода: - (
Шесть действительно плохих примеров;
System.exit
без предупреждения. например if(properties.size()>10000) System.exit(0);
похоронен глубоко в
библиотека.synchronized("one") { }
.synchronized(object) { object = ...; }
.try { Integer i = null; i.intValue(); } catch(NullPointerException e) { e.printStackTrace(); }
.new Integer(text).intValue() or worse new Integer(0).getClass()
Я ненавижу, когда люди создают интерфейсы только для того, чтобы навешивать набор констант на:
public interface InterfaceAntiPattern {
boolean BAD_IDEA = true;
int THIS_SUCKS = 1;
}
— Интерфейсы предназначены для определения поведенческих контрактов, а не для удобства для включения констант.
if{
if{
if{
if{
if{
if{
if{
if{
....
Не связано строго с Java, но снова и снова вызывает дорогостоящую функцию вместо сохранения результата, когда вы знаете, что это не изменится. Пример:
if (expensiveFunction() > aVar)
aVar = expensiveFunction();
for (int i=0; i < expensiveFunction(); ++i)
System.out.println(expensiveFunction());
Худшая практика Java, которая охватывает почти все остальные: Глобальное изменяемое состояние.
Смешная манера OO с уровнями иерархии классов 10+.
Здесь появляются имена типа DefaultConcreteMutableAbstractWhizzBangImpl
. Просто попробуйте отладить этот код - вы будете часами прокручивать вверх и вниз по дереву классов.
Подклассификация, когда вы не должны, например, вместо использования композиции, агрегации и т.д.
Изменить: Это особый случай молотка.
увидел что-то вроде этого:
public static boolean isNull(int value) {
Integer integer = new Integer(value);
if(integer == null) {
return true;
} else {
return false;
}
}
У них был подобный метод для longs.
Я предполагаю, что они изначально сделали что-то вроде
if(value == null) {
и получил ошибку компиляции и все еще не понимал, что примитивные значения не могут быть нулевыми.
Наш стажер использовал модификатор static
для хранения зарегистрированного пользователя в приложении Seam.
class Identity{
...
public static User user;
...
}
class foo{
void bar(){
someEntity.setCreator(Identity.user);
}
}
Конечно, это сработало, когда он протестировал его:)
Не закрывать подключения к базе данных, файлы и т.д. в конце {}
Мне приходилось исследовать веб-приложение, в котором ВСЕ-состояние хранилось на веб-странице, отправленной клиенту, и на веб-сервере не было никакого состояния.
Хорошо масштабируется:)
API, который требует вызова вызывающего абонента:
Foobar f = new Foobar(foobar_id);
f = f.retrieve();
Любое из следующих было бы лучше:
Foobar f = Foobar.retrieve(foobar_id);
или
Foobar f = new Foobar(foobar_id); // implicit retrieve
или
Foobar f = new Foobar();
f.retrieve(foobar_id); // but not f = ...
Абстрактная функциональность в классе библиотеки, которая никогда не будет использоваться повторно, поскольку она настолько специфична для исходной проблемы, которая решается. Следовательно, заканчивая библиотечными классами gazillion, которые никто никогда не будет использовать, и которые полностью скрывают две полезные утилиты, которые вы на самом деле делаем (т.е. CollectionUtils
и IOUtils
).
... паузы для дыхания...
Создание акцессоров и мутаторов для всех частных переменных, не останавливаясь, а иногда и автоматически.
Инкапсуляция была изобретена по какой-то причине.
Оверкаль абстракция объектно-ориентированного дизайна (удалено так 10k).
Тот же ответ на аналогичный поток (применим ко всем языкам, которые разрешают объектно-ориентированный дизайн).
После длительного воздействия Java делает это для некоторых людей.
Почему? Мое мнение таково, что это потому, что там слишком много Intellisense и никакого смысла. Это позволяет вам делать глупые вещи так быстро, что люди не перестают думать.
Пример 1:
boolean negate( boolean shouldNegate, boolean value ) {
return (shouldNegate?(!value):value;
}
который, конечно же, совпадает с значением ^ shouldNegate, простым XOR.
Пример 2: (клянусь, что я этого не делаю)
boolean isNotNull( Object o ) {
return o != null;
}
Оба с дополнительными 4-6 строками Javadoc, объясняя, что делали эти методы.
Пример 3:
/**
*
*
*/
Пустой Javadoc, чтобы избежать раздражающих предупреждений Eclipse "Javadoc".
Пример 3b:
/**
* A constructor. Takes no parameters and creates a new instance of MyClass.
*/
public MyClass() {
}
Мой любимый алгоритм сортировки, любезно предоставленный бригадой серой бороды:
List needsToBeSorted = new List ();
...blah blah blah...
Set sorted = new TreeSet ();
for (int i = 0; i < needsToBeSorted; i++)
sorted.add (needsToBeSorted.get (i));
needsToBeSorted.clear ();
for (Iterator i = sorted.iterator (); i.hasNext ();)
needsToBeSorted.add (i.next ());
По общему признанию, это сработало, но в конечном итоге я превалировал над ним, что, возможно, Collections.sort было бы намного проще.
Я видел эту пару пару минут назад:
Short result = new Short(new Integer(new Double(d).intValue()).shortValue());
В File I/O: неправильное использование блока try-catch.
try {
/* open file */
}
catch(Exception e) {
e.printStackTrace();
}
try {
/* read file content */
}
catch (Exception e) {
e.printStackTrace();
}
try {
/* close the file */
}
catch (Exception e) {
e.printStackTrace();
}
@madlep Точно! Части сообщества Java действительно выходят за борт с экстремальными абстракциями и безумно глубокими иерархиями классов. Стив Йегге написал об этом пару месяцев назад: Исполнение в Королевстве существительных.
Определение логики с использованием исключений, где достаточно петли или любой формы цикла.
Пример:
while(i < MAX_VALUE)
{
try
{
while(true)
{
array[j] = //some operation on the array;
j++;
}
}
catch(Exception e)
{
j = 0;
}
}
Серьезный, я знаю парня, который написал этот код. Я просмотрел его и скорректировал код:)
Как и ваш, но сделал еще один шаг:
Использование переменных класса (статических), когда переменная с охватом запроса была правильной вещью в действии Struts.: О
Это фактически было развернуто в производстве в течение нескольких месяцев, и никто не заметил ничего, пока я не просмотрел код в один прекрасный день.
Excesive focuse для повторного использования объектов, которые приводят к статическим вещам повсюду. (Указанное повторное использование может быть очень полезным в некоторой ситуации).
Java имеет встроенный GC, если вам нужен объект, создайте новый.
Вот обрезанный образец из фактического апплета, который я должен был поддерживать, он вел меня навсегда, чтобы понять, что делает.
int sval, eval, stepv, i;
double d;
if (/*someCondition*/)
{
sval = 360;//(all values multiplied by 20)
eval = -271;
stepv = -10;
}
else if (/*someCondition*/)
{
sval = 320;
eval = -601;
stepv = -10;
}
else if (/*someCondition*/)
{
sval = 0;
eval = -311;
stepv = -10;
}
else
{
sval = 360;
eval = -601;
stepv = -10;
}
for (i = sval; i > eval; i = i + stepv)
{
d = i;
d = d / 20.0;
//do some more stuff in loop
}
оказывается, что он хотел итерации на .5 по петле и это не ошибка вставки, то есть схема отступа
Огромные имена классов. Я помню: AbstractTableComponentListeningBehaviourPanel.java
и другие подобные монстры.
Худшая часть - даже если соглашение об именах было сумасшедшим, мне все же пришлось отбирать файлы для разработки их целей.
Ошибка младших программистов: без необходимости использовать переменные-члены вместо локальных переменных.
Пример Java EE:
Запуск потоков в сервлетах или EJB (например, для запуска задач асинхронной обработки).
Это нарушает масштабируемость вашего приложения Java EE. Вы не должны возиться с потоками в компонентах Java EE, потому что сервер приложений должен управлять этим для вас.
Мы реорганизовали это, если сервлет поставил сообщение в очередь JMS и написал управляемый сообщениями bean для обработки задачи асинхронной обработки.
Я думаю, что для меня это должен быть рекорд. Класс используется для построения сложной модели данных для передней части, включающей фильтрацию. поэтому метод, возвращающий список объектов, выглядит примерно так:
public DataObjectList (GenerateList (massive signature involving 14 parameters, three of which are collections and one is a collection of collections)
try {
250 lines of code to retrieve the data which calls a stored proc that parses some of it and basically contains GUI logic
} catch (Exception e) {
return new DataObjectList(e, filterFields);
}
Итак, я пришел сюда, потому что мне было интересно, как получилось, что следующий вызывающий метод терпит неудачу, и я не мог видеть, где было задано поле "Исключение".
DataObjectList dataObjectList= EntireSystemObject.getDataObjectList Generator().generateDataObjectList (viewAsUserCode, processedDataRowHandler, folderQuery, pageNumber, listCount, sortColumns, sortDirections, groupField, filters, firstRun, false, false, resetView);
dataObjectList.setData(processedDataRowHandler.getData());
if (dataObjectList.getErrorException() == null) {
do stuff for GUI, I think, put lots of things into maps ... 250 lines or so
}
return dataObjectList;
} else {
put a blank version into the GUI and then
throw new DWRErrorException("List failed due to list generation error", "list failed due to list generation error for folder: " + folderID + ", column: " + columnID, List.getErrorException(), ListInfo);
}
Все со мной до сих пор?
Ну, по крайней мере, они сказали нам в передней части, что что-то действительно пошло не так!
AbstractSpringBeanFactoryFactoryFacadeMutatorBeanFactory. Я не выношу этого сверхразвитого, непонятного БС. Бенджи Смит добавляет немного более элегантно.