В чем причина этих правил PMD? - PullRequest
34 голосов
/ 23 октября 2009

DataflowAnomalyAnalysis: Found 'DD' -аномалия для переменной 'variable' (строки 'n1' - 'n2').

DataflowAnomalyAnalysis: Found 'DU' -аномалия для переменной 'variable' (строки 'n1' - 'n2').

DD и DU звучат знакомо ... Я хочу сказать о таких вещах, как тестирование и анализ, относящихся к самым слабым условиям до и после, но я не помню особенностей.

NullAssignment: назначение объекта ноль - это запах кода. Рассматривать рефакторинга.

Не поможет ли установка объекта на null помочь в сборке мусора, если объект является локальным объектом (не используется вне метода)? Или это миф?

MethodArgumentCouldBeFinal: Параметр 'param' не назначен и может быть объявлен окончательным

LocalVariableCouldBeFinal: Local переменная переменная может быть объявлена Окончательный

Есть ли какие-либо преимущества в использовании final параметров и переменных?

Свободная связь: избегать использования типы реализации, такие как 'LinkedList'; использовать интерфейс вместо

Если я знаю, что мне конкретно нужен LinkedList, почему бы мне не использовать его, чтобы четко изложить свои намерения будущим разработчикам? Одно дело возвращать класс, который находится выше пути к классу, что имеет смысл, но почему бы мне не объявить, что мои переменные имеют самый строгий смысл?

AvoidSynchronizedAtMethodLevel: использовать уровень блока, а не уровень метода синхронизация

Какие преимущества имеет синхронизация на уровне блоков по сравнению с синхронизацией на уровне методов?

AvoidUsingShortType: не используйте короткий тип

Моими первыми языками были C и C ++, но в мире Java, почему я не должен использовать тип, который лучше всего описывает мои данные?

Ответы [ 6 ]

33 голосов
/ 23 октября 2009
  • Аномалии DD и DU (если я правильно помню & mdash; я использую FindBugs, а сообщения немного отличаются) относятся к присвоению значения локальной переменной, которая никогда не читается, обычно потому, что ей было присвоено другое значение ранее будучи прочитанным Типичным случаем будет инициализация некоторой переменной с null, когда она объявлена. Не объявляйте переменную, пока она не понадобится.

  • Назначение null локальной переменной для «помощи» сборщику мусора - миф. PMD сообщает вам, что это просто контрпродуктивный беспорядок.

  • Указание final для локальной переменной должно быть очень полезным для оптимизатора, но у меня нет конкретных примеров того, как текущие JIT используют эту подсказку. Я нашел это полезным в рассуждениях о правильности моего собственного кода.

  • Указание интерфейсов в терминах & hellip; ну, интерфейсы - отличная практика проектирования. Вы можете легко изменить реализации коллекции, не влияя на вызывающего. Вот что такое интерфейсы.

  • Я не могу вспомнить многих случаев, когда вызывающему абоненту требуется a LinkedList, так как он не предоставляет API, который не объявлен каким-либо интерфейсом. Если клиент использует этот API, он доступен через правильный интерфейс.

  • Синхронизация на уровне блоков позволяет уменьшить критическую секцию, что позволяет одновременно выполнять как можно больше работы. Возможно, еще важнее то, что он позволяет использовать объект блокировки, который находится в частном управлении с помощью включающего объекта. Таким образом, вы можете гарантировать отсутствие тупиковой ситуации. Используя сам экземпляр в качестве блокировки, любой может синхронизироваться с ним неправильно, вызывая взаимоблокировку.

  • Операнды типа short повышаются до int в любых операциях. Это правило позволяет вам знать, что эта акция происходит, и вы также можете использовать int. Однако использование типа short может сэкономить память, поэтому, если это элемент экземпляра, я бы, вероятно, проигнорировал это правило.

3 голосов
/ 15 декабря 2010

Просто примечание к вопросу final.

Помещение "final" в переменную приводит к тому, что она может быть назначена только один раз . Это не обязательно означает, что писать легче, но это, безусловно, означает, что читать легче для будущего сопровождающего.

Пожалуйста, учтите эти моменты:

  • любая переменная с final может быть немедленно классифицирована как «не будет изменять значение во время просмотра».
  • подразумевается, что если все переменные, которые не будут изменены, помечены как final, то переменные, не помеченные как final, действительно БУДУТ изменяться.

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

3 голосов
/ 23 октября 2009

DataflowAnomalyAnalysis: Found 'DD' -аномалия для переменной 'variable' (строки 'n1' - 'n2').

DataflowAnomalyAnalysis: Found 'DU' -аномалия для переменной 'variable' (строки 'n1' - 'n2').

Не знаю.

NullAssignment: назначение объекта ноль - это запах кода. Рассматривать рефакторинга.

Не поможет ли установка объекта на null помочь в сборке мусора, если объект является локальным объектом (не используется вне метода)? Или это миф?

Объекты в локальных методах помечаются как сборщики мусора после возврата метода. Установка их в ноль не будет иметь никакого значения.

Поскольку разработчикам было бы меньше опыта, то что это за нулевое назначение, можно считать запахом кода.

MethodArgumentCouldBeFinal: Параметр 'param' не назначен и может быть объявлен окончательным

LocalVariableCouldBeFinal: Local переменная переменная может быть объявлена Окончательный

Есть ли какие-либо преимущества в использовании final параметров и переменных?

Понятно, что значение не изменится в течение жизненного цикла объекта.

Кроме того, если кто-то случайно попытается присвоить значение, компилятор предотвратит эту ошибку кодирования при типе компиляции.

рассмотрим это:

 public void businessRule( SomeImportantArgument important )  {
      if( important.xyz() ){
          doXyz();
      }
      // some fuzzy logic here
      important = new NotSoImportant();
      // add for/if's/while etc 

     if( important.abc() ){ // <-- bug
         burnTheHouse();
     }
  } 

Предположим, вам поручено решить какую-то загадочную ошибку, которая время от времени сжигает дом.

Вы знаете, что это за параметр, который вы не понимаете: ПОЧЕМУ метод burnTHeHouse вызывается, если условия не выполняются (согласно вашим выводам)

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

Использование final помогает предотвратить подобные вещи.

Свободная связь: избегать использования типы реализации, такие как 'LinkedList'; использовать интерфейс вместо

Если я знаю, что мне конкретно нужен LinkedList, почему бы мне не использовать его, чтобы четко обозначить свои намерения для будущих разработчиков? Одно дело возвращать класс, который является наивысшим по сравнению с путем к классу, что имеет смысл, но почему бы мне не объявить, что мои переменные имеют самый строгий смысл?

В этом случае разницы нет. Я думаю, что, поскольку вы не используете LinkedList специальные функции, предложение справедливо.

Сегодня LinkedList может иметь смысл, но с помощью интерфейса вы помогаете себе (или другим) легко изменить его, когда это не нужно.

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

Также, помогает менее опытному разработчику создавать хорошие привычки. [Я не говорю, что вы один, но анализатор не знает вас;)]

AvoidSynchronizedAtMethodLevel: использовать уровень блока, а не уровень метода синхронизация

Какие преимущества имеет синхронизация на уровне блоков по сравнению с синхронизацией на уровне методов?

Чем меньше синхронизированный раздел, тем лучше. Вот и все.

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

AvoidUsingShortType: не используйте короткий тип

Моими первыми языками были C и C ++, но в мире Java, почему я не должен использовать тип, который лучше всего описывает мои данные?

Я никогда не слышал об этом, и я согласен с вами :) Хотя я никогда не использую шорт.

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

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

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

Если совет не имеет смысла, просто проигнорируйте их, помните, что вы разработчик, а инструмент - это просто инструмент. Если что-то пойдет не так, вы не можете винить инструмент, верно?

1 голос
/ 24 октября 2009

Не установил бы объект в нуль помочь в сборке мусора, если объект является локальным объектом (не используется вне метода)? Или это миф?

Единственное, что он делает, - это позволяет объекту быть GCd до конца метода, что редко когда-либо необходимо.

Есть ли какие-либо преимущества в использовании конечных параметров и переменных?

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

Если я знаю, что мне конкретно нужно LinkedList, почему бы мне не использовать один для четко изложить свои намерения будущие разработчики?

Можете ли вы вспомнить причину, по которой вам конкретно LinkedList?

Одно дело вернуть класс, который является наивысшим путь класса, который имеет смысл, но почему я бы не объявил мои переменные в самом строгом смысле?

Меня не волнуют локальные переменные или поля, но если вы объявите параметр метода типа LinkedList, я выследу вас и сделаю вам больно, потому что я не могу использовать такие вещи, как Arrays.asList() и Collections.emptyList().

Какие преимущества имеет синхронизация на уровне блоков по сравнению с синхронизацией на уровне методов?

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

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

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

0 голосов
/ 18 марта 2010

Какие преимущества дает блок-уровень синхронизация имеет уровень метода Синхронизация? Синхронизировать метод аналогично блоку synchronize(getClass()) и блокировать весь класс.

Может быть, вы этого не хотите

0 голосов
/ 24 октября 2009

AvoidUsingShortType: не используйте короткий тип

  • Элемент списка

    шорт 16 бит, комплимент 2 в java

  • короткая математическая операция с чем-либо в семействе Integer, за исключением другого короткого, потребует преобразования расширения знака времени выполнения в больший размер. работа с плавающей запятой требует расширения знака и нетривиального преобразования в IEEE-754.
  • не может найти доказательства, но с 32-битным или 64-битным регистром вы больше не экономите на «инструкциях процессора» на уровне байт-кода. Что касается регистра процессора, то вы припарковали компактный автомобиль на месте парковки полуприцепа.
  • Если вы оптимизируете свой проект на уровне байтового кода, вау. Просто вау. ; Р
  • Я согласен с тем, что при проектировании игнорируется это предупреждение pmd, просто взвешиваю, точно описывая ваш объект с «короткими» и произведенными преобразованиями производительности.
  • по моему мнению, потери производительности на большинстве машин незначительны. игнорировать ошибку.
...