Действительно ли это проблематично для присвоения нового значения параметру метода?

Eclipse имеет опцию предупредить о присвоении на параметр метода (в методе), как в:

public void doFoo(int a){
   if (a<0){
      a=0; // this will generate a warning
   }
   // do stuff
}

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

Я вижу законные случаи для изменения параметра в методе (например: Разрешение параметра быть "сброшенным" (например, пустой указатель) и автоматически замена значением по умолчанию), но немного ситуаций, где это вызвало бы проблемы, за исключением того, что это могло бы немного сбивать с толку для переприсвоения параметра посреди метода.

Вы используете такие предупреждения? Почему / почему нет?

Примечание:

Предотвращение этого предупреждения, конечно, эквивалентно созданию параметра метода final (только затем это - ошибка компилятора :-)). Так этот вопрос, Почему я должен использовать ключевое слово "финал" на параметре метода в Java? мог бы быть связан.

20
задан Community 23 May 2017 в 10:29
поделиться

8 ответов

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

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

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

10
ответ дан 29 November 2019 в 23:57
поделиться

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

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

8
ответ дан 29 November 2019 в 23:57
поделиться

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

13
ответ дан 29 November 2019 в 23:57
поделиться

Переназначение переменной параметра метода обычно является ошибкой, если параметр является ссылочным типом.

Рассмотрим следующий код:

MyObject myObject = new myObject();
myObject.Foo = "foo";
doFoo(myObject);

// what's the value of myObject.Foo here?

public void doFoo(MyObject myFoo){   
   myFoo = new MyObject("Bar");
}

Многие люди ожидают, что at после вызова doFoo myObject.Foo будет равно «Bar». Конечно, не будет - потому что Java не передается по ссылке , а передается по значению ссылки , то есть копия ссылки передается методу. Переназначение этой копии влияет только на локальную область видимости, но не на callite. Это одна из наиболее часто неправильно понимаемых концепций.

7
ответ дан 29 November 2019 в 23:57
поделиться

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

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

2
ответ дан 29 November 2019 в 23:57
поделиться

Иногда я использую его в таких ситуациях:

void countdown(int n)
{
   for (; n > 0; n--) {
      // do something
   }
}

, чтобы не вводить переменную i в цикл for. Обычно я использую такие «уловки» только в очень коротких функциях.

Лично мне очень не нравится "исправлять" параметры внутри функции таким образом. Я предпочитаю ловить их утверждениями и удостоверяться в правильности контракта.

0
ответ дан 29 November 2019 в 23:57
поделиться

Вы пишете код без побочных эффектов : каждый метод shoud - это функция , которая не изменяется . В противном случае это команда и это может быть опасно.

См. определения команды и функции на веб-сайте DDD :

Функция : Операция, которая вычисляет и возвращает результат без видимых побочных эффектов.

Команда : Операция, которая влияет на некоторые изменения в системе (для например, установка переменной). . операция, которая намеренно создает Побочное действие.

-1
ответ дан 29 November 2019 в 23:57
поделиться

Обычно мне не нужно назначать новые значения параметрам метода.

Что касается передового опыта - предупреждение также позволяет избежать путаницы при столкновении с кодом вроде:

       public void foo() {
           int a = 1;
           bar(a);
           System.out.println(a);
       }

       public void bar(int a) {
           a++;
       }
0
ответ дан 29 November 2019 в 23:57
поделиться
Другие вопросы по тегам:

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