2014-04-07 2 views
0

Что я имею в виду? Проще всего показать по кодуСсылка на ссылку или возврат

import java.util.Date; 

public class Example { 

    public static void main(String... args) { 
    Date d1 = new Date(2014,4,7); 
    Date d2 = new Date(2014,4,7); 

    methodA(d1); 
    System.out.println("Month of d1: " +d1.getMonth()); 

    d2 = methodB(d2); 
    System.out.println("Month of d2: " +d2.getMonth()); 
    } 

    public static void methodA(Date d) { 
    d.setMonth(6); 
    } 

    public static Date methodB(Date d) { 
    d.setMonth(6); 
    return d; 
    } 

} 

Прежде всего, игнорируйте устаревший код даты. Когда речь идет о изменяемых объектах, таких как Date, лучше сделать изменение и вернуть ссылку, как в методе methodB, или нормально использовать метод methodA?

Я подозреваю, что метод B - это то, что выбирают большинство людей, но почему?

Метод примечанийА имеет тот же результат, что и метод B при использовании изменяемых объектов. Поменяйте даты для целого числа, например, и значение останется неизменным для первого объекта после вызова методаA (предполагая, что метод A и метод B будут делать простой приращение на двух целых ссылках того же значения)

+0

я не сказал бы, что 'methodB' - это то, что выбирают большинство людей. в некоторых случаях необходимо использовать 'methodB', в других случаях это не имеет значения. – mangusta

+2

Вау, вопрос с 0 upvotes и 7 ответами с 0 upvotes .. должен быть какой-то рекорд! –

+0

Все еще подбрасывать между выбиванием и пометкой, как в основном на основе мнения .. не может решить, arg! –

ответ

3

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

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

public static Date methodB(Date d) { 
    Date result = d.clone(); 
    result.setMonth(6); 
    return result; 
} 

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

public class DateManipulator { 

    public DateManipulator(Date d) { 
    // store d 
    } 

    public static DateManipulator methodB() { 
    d.setMonth(6); 
    return this; 
    } 

    public static Date build() { 
    return d; 
    } 
} 

Который позволяет конструкта:

new DateManipulator(d).methodB().methodC()....build(); 
+0

Спасибо, и если методB был изменен, как вы предполагали, будет ли метод все еще вашим предпочтением? – PDStat

+0

@PaulStatham Я лично выбрал 'methodA', так как он оставил бы вызов клонирования (или что-то еще) вызывающего. Во многих случаях им не нужно сохранять предыдущее состояние объекта. –

0

Большинство людей предпочли бы вариант 2, поскольку он позволяет цепочки:

Example.methodB(...).someThing() 

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

Общий пример - класс StringBuilder. StringBuilder.append() возвращает StringBuilder (this), поэтому вы можете подключить команды append().

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

0

В общем Я бы предпочел methodA, так как я бы подумал о возврате другого объекта, поскольку подразумевается, что оригинал не изменяется. Все методы обработки String являются примерами.

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

0

Это ни лучше, ни хуже. Это зависит от ситуации.

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

public Example methodC(Date d) { 
    d.setMonth(6); 
    return this; 
} 

Хотя методы с побочными эффектами, как это (и я бы рассмотреть вопрос об изменении свойства переданного в параметре быть побочным эффект, в большинстве случаев) следует избегать, большинство времени.

0

Я думаю, есть молчаливое соглашение о том, что вы действительно не изменяете параметр метода, как на Java. Есть исключения из этого, например, метод Collections.sort и т. Д. В Ruby неплохо, что методы, изменяющие параметры, отмечены восклицательным знаком (!). Но нет, изменения параметра Integer и String не влияют на значения вне области метода. Насколько я знаю, у них есть объекты в пуле целых чисел/строк.

0

«Подозреваю, что метод B - это то, что выбирают большинство людей, но почему?»

не очень, methodA обновления поля month в объекте d1, такие же, как метод methodB будет делать, и как метод methodB возвращает переданный объект, оператор возврата излишне

, который означает, что большинство людей на самом деле идут с methodA