Использование этого в другом конструкторе - PullRequest
3 голосов
/ 08 марта 2012

Предположим, у вас есть класс с этим конструктором:

public SomeObj(int x, int y) {
    this.x = x;
    this.y = y;
}

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

public SomeObj(SomeObj objectToClone) { ... }

Но какой из следующих двух способов лучше? Каковы преимущества и недостатки (производительность (байт-код), удобочитаемость ...)?

// 1
public SomeObj(SomeObj objectToClone) {
    this.x = objectToClone.x;
    this.y = objectToClone.y;
}

// 2
public SomeObj(SomeObj objectToClone) {
    this(objectToClone.x, objectToClone.y);
}

Ответы [ 6 ]

13 голосов
/ 08 марта 2012

Я бы пошел с последним лично.

Где это возможно, я стараюсь, чтобы точно один конструктор имел "реальное" тело, и заставлял все остальные делегировать его.Это не всегда возможно - в частности, разные конструкторы могут нуждаться в делегировании разным суперконструкторам - но приятно знать, что есть одно место, где вы можете поместить дополнительную инициализацию, ведение журнала, точки останова и т. Д., Которые всегда будут попадать.

3 голосов
/ 08 марта 2012

Номер 2 лучше. Зачем? потому что вы больше не повторяете себя, устанавливая член в двух разных конструкторах.

На самом деле нет никакого снижения производительности, если только незначительная дополнительная косвенность вызова this() не повлияет на вас (и я сомневаюсь, что вы даже можете точно измерить эту разницу).

2 голосов
/ 08 марта 2012

Если вы используете второй вариант, вам не нужно менять public SomeObj(SomeObj objectToClone) каждый раз, когда вы меняете реализацию public SomeObj(int x, int y). Так что это лучше, так как позволяет избежать дублирования кода.

1 голос
/ 08 марта 2012

Это не C ++. Переопределите метод .clone () из класса Object для копирования объектов. Это верный путь

1 голос
/ 08 марта 2012

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

0 голосов
/ 08 марта 2012
// 1
public SomeObj(SomeObj objectToClone) {
    this.x = objectToClone.x;
    this.y = objectToClone.y;
}

лучше.

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

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

Сравните эти два значения:

public SomeObj(SomeObj objectToClone) {
    this.x = objectToClone.x;
    this.y = objectToClone.y;
    this.z = objectToClone.z;
    this.p = objectToClone.p;
    this.s = objectToClone.s;
    this.a = objectToClone.a;
    this.b = objectToClone.b;
    }

и затем наберите SomeObj(obj) 10 раз в вашем коде.

против SomeObj(obj.x,obj.y,obj.z,obj.p,obj.s,obj.t,obj.a,obj.b); 10 раз в вашем коде

Кроме того, со вторым вариантом вы не можете гарантировать, что переданные параметры соответствуют вашим требованиям, поэтому вы можете получить что-то вроде этого: SomeObj(obj.x,obj.y,obj2.z,obj3.p,0,0,-1,null);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...