0

我在一本 Java 书籍中做一个项目,并遇到了这个代码示例。这本书的作者说,与其直接在我的构造函数中初始化 X 和 Y,我可以调用类的 setLocation() 方法来代替。不幸的是,我不再有这本书来具体解释为什么这会更好。我对 Java 的经验不是很丰富,但它不只是......更简单地直接分配值而不用担心另一个函数调用吗?

//Point constructor, normal way of initializing variables

private double x;
private double y;

Point(double initial_x, double initial_y)
{
 this.x = initial_x;   
 this.y = initial_y;
} 

//Point constructor, the other way

Point(double initial_x, double initial_y)
{ 
   setLocation(initial_x, initial_y);
} 


public void setLocation(double newX, double newY)
{
   this.x = newX;
   this.y = newY; 
}
4

7 回答 7

6

我实际上建议不要在构造函数中调用 setter,因为从构造函数中调用可覆盖的方法是个坏主意。此外,getter/setter 的常见论点是逻辑可能会改变,您不必更改访问您的属性的每个人。但是,在这种情况下,如果逻辑发生更改,则必要的更改仅限于同一类。

于 2010-09-03T01:42:34.400 回答
2

与上面其他人所说的相同,还有一个警告:

如果您出于并发或其他原因需要不可变对象,我可以看到反对这种做法的论据。如果你正在做任何可能有多个线程作用于这个对象的事情,那么 setter 可能会给你带来麻烦。

于 2010-09-03T01:43:58.810 回答
1

因为在任何示例中两个实例变量都是私有的,所以setLocation()在此上下文中的目的似乎是允许其他类在Point对象初始化后修改对象的坐标。并且由于构造函数会有效地完成相同的事情(再次仅用于这个简单的示例),构造函数只是为了简单起见调用该方法。

于 2010-09-03T01:41:27.490 回答
0

您可以更好地控制它们的设置时间。

于 2010-09-03T01:42:03.887 回答
0

如果设置成员涉及一些逻辑,并且您的类是可变的(提供一个行为类似于第二次调用构造函数的方法),那么使用初始化方法是有意义的。

private int width;
private int height;
private double diagonal;

Image(int initial_w, int initial_h)
{
 Init(initial_w, initial_h)
}

public void Init(int initial_w, initial_h)
{
 width = initial_w;
 height = initial.h
 diagonal = Math.sqrt(width*width + height*height); // constructor doesn't need to repeat this line
}
于 2010-09-03T01:44:41.947 回答
0

如果xy是可变的并且具有非平凡的设置器,那么使用设置器来初始化它们,即使在构造函数中,也可以帮助避免代码重复。在这种情况下,您可能希望将 setter 标记为final防止派生类覆盖这些方法并导致构造函数出现意外行为的可能性。

如果设置器是微不足道的(没有其他代码的简单赋值),那么没有太多理由在构造函数中使用设置器。

如果变量是不可变的,最好根本没有设置器并直接在构造函数中初始化它们。

于 2010-09-03T01:53:32.680 回答
-1

此资源可能会有所帮助:

http://en.wikipedia.org/wiki/JavaBean

我个人发现没有参数的构造函数可以简化依赖注入。例如,使用 Spring IoC,虽然您当然可以指定构造函数参数,但不必这样做要简单得多。

我还发现,出于同样的原因,编写单元测试更简单,即您可以实例化您想要的对象,注入测试所需的属性,然后进行测试。因此,拥有带有 args 的构造函数可能需要您使用您对测试并不特别感兴趣的对象进行设置。

也就是说,提供无参数构造函数与提供方便的带参数构造函数并不相互排斥,即您可以同时拥有两者;只需确保您有一个无参数来满足上述用例。

于 2010-09-03T02:11:18.950 回答