Сложно ли назначать новое значение параметру метода?
Eclipse имеет возможность предупреждать о назначении параметру метода (внутри метода), например:
public void doFoo(int a){
if (a<0){
a=0; // this will generate a warning
}
// do stuff
}
Обычно я пытаюсь активировать (и прислушиваться) почти все доступные предупреждения компилятора, но в этом случае я не уверен, стоит ли это.
Я вижу законные случаи для изменения параметра в методе (например: разрешение параметра "unset" (например, null) и автоматическая подстановка значения по умолчанию), но в нескольких ситуациях, когда это может вызвать проблемы, за исключением того, что оно может быть немного запутанным, чтобы переназначить параметр в середине метода.
Используете ли вы такие предупреждения? Почему/почему нет?
Примечание:
Избежать этого предупреждения, конечно, эквивалентно созданию параметра метода final
(только тогда это ошибка компилятора:-)). Итак, этот вопрос Почему я должен использовать ключевое слово "final" по параметру метода в Java? может быть связано.
Ответы
Ответ 1
Для меня, пока вы делаете это рано и ясно, это прекрасно. Как вы говорите, это глубоко погружено в четыре условности на полпути в 30-строчную функцию, которая меньше идеальной.
Вы также должны быть осторожны, когда делаете это с объектными ссылками, поскольку вызовы методов на заданном вами объекте могут изменять его состояние и передавать информацию обратно вызывающему, но, конечно, если вы зашли в свой собственный placeholder, эта информация не передается.
Обратная сторона заключается в том, что объявление новой переменной и назначение аргумента (или аргумент по умолчанию, если аргумент нуждается в дефолте), он может быть более ясным и почти наверняка не менее эффективен - любой достойный компилятор (будь то первичный компилятор или JIT) оптимизирует его, когда это возможно.
Ответ 2
Запутанная часть является причиной предупреждения. Если вы переназначите параметр новым значением в методе (вероятно, условным), тогда неясно, что такое a. Вот почему это считается хорошим стилем, чтобы оставить параметры метода без изменений.
Ответ 3
Назначение параметра метода не является чем-то большим, чем большинство людей ожидают в большинстве методов. Поскольку мы читаем код с предположением, что значения параметра фиксированы, назначение обычно считается плохой практикой, если только по соглашению и принцип наименьшего удивления.
Всегда есть альтернативы для назначения параметров метода: обычно локальная временная копия просто прекрасна. Но в целом, если вы обнаружите, что вам нужно управлять логикой вашей функции с помощью переназначения параметров, она может извлечь выгоду из реорганизации в более мелкие методы.
Ответ 4
Переназначение переменной параметра метода обычно является ошибкой, если параметр является ссылочным типом.
Рассмотрим следующий код:
MyObject myObject = new myObject();
myObject.Foo = "foo";
doFoo(myObject);
// what the value of myObject.Foo here?
public void doFoo(MyObject myFoo){
myFoo = new MyObject("Bar");
}
Многие ожидают, что после вызова doFoo myObject.Foo будет равен "Bar". Конечно, это не будет - потому что Java не проходит по ссылке, но проходит по ссылочному значению - то есть копия ссылки передается методу. Переназначение этой копии влияет только на локальную область, а не на callsite. Это одна из наиболее часто понятых концепций.
Ответ 5
Различные предупреждения компилятора могут быть подходящими для разных ситуаций. Конечно, некоторые применимы к большинству или ко всем ситуациям, но это, похоже, не одно из них.
Я бы подумал об этом конкретном предупреждении, поскольку компилятор дает вам возможность быть предупрежденным о том, что параметр метода переназначается, когда вам это нужно, а не правило, которое параметры метода не следует переназначать. Ваш пример представляет собой вполне обоснованный случай для него.
Ответ 6
Я иногда использую его в таких ситуациях:
void countdown(int n)
{
for (; n > 0; n--) {
// do something
}
}
чтобы избежать ввода переменной я в цикл for. Обычно я использую только эти "трюки" в очень коротких функциях.
Лично мне очень не нравятся "исправление" параметров внутри функции таким образом. Я предпочитаю поймать их по утверждениям и убедиться, что контракт прав.
Ответ 7
Мне обычно не нужно назначать новые значения параметрам метода.
Что касается лучших практик - предупреждение также позволяет избежать путаницы при обращении к коду вроде:
public void foo() {
int a = 1;
bar(a);
System.out.println(a);
}
public void bar(int a) {
a++;
}
Ответ 8
Вы записываете код без побочного эффекта: каждый метод shoud будет функцией, которая не изменяется. В противном случае это команда, и это может быть опасно.
См. определения команда и function on сайт DDD:
Функция: Операция, которая вычисляет и возвращает результат без наблюдаемых побочных эффектов.
Команда: операция, которая влияет на некоторые изменения в системе (для пример, установка переменной). операции, которая преднамеренно создает побочный эффект.