在java中初始化没有new运算符的对象

时间:2016-03-30 12:17:11

标签: java

这两个构造函数之间的区别是什么。

Circle (Point2D center, double radius) {
    this.center = center;
    this.radius = radius;
}

Circle (Point2D center, double radius) {
    this.center = new Point2D(center.getX(), center.getY());
    this.radius = radius;
}

继承Point2D课程。这两个版本的构造函数都运行得很好。我感到困惑的是差异。

class Point2D {
double x;
double y;

Point2D () {
    x = 0;
    y = 0;
}

Point2D (double x, double y) {
    this.x = x;
    this.y = y;
}

void setX (double x) {
    this.x = x;
}

void setY (double y) {
    this.y = y;
}

void setXY (double x, double y) {
    this.x = x;
    this.y = y;
}

double getX () {
    return x;
}

double getY () {
    return y;
}

double distance (Point2D p) {
    double x1 = p.getX();
    double y1 = p.getY();
    return Math.sqrt(Math.pow(x1 - x, 2) + Math.pow(y1 - y, 2));
}

double distance (double x, double y) {
    return Math.sqrt(Math.pow(x - this.x, 2) + Math.pow(y - this.y, 2));
}

}

Circle类还有2个中心和半径。 center是Point2D类型,radius是double类型。我尝试编译并运行两个版本的构造函数。两者都运作良好。所以我很困惑哪一个会更好用,为什么,也有区别,因为在第一个我没有使用新操作来初始化中心对象。

4 个答案:

答案 0 :(得分:4)

第二个构造函数使用原始Point2D实例的defensive copy(由center构造函数调用生成)以防止输入实例的进一步突变(更改),这可能非常令人困惑,产生错误

  

所以我很困惑哪一个会更好用,为什么

第二种方法更安全,因为您的Point2D类是可变的。它使用更多的内存(以保持额外的防御性副本),但在真正复杂的项目中,这种设计实践的优点多于缺点。

如果你可以使Point2Dimmutable,那么可以使用第一个构造函数。

答案 1 :(得分:3)

第二个构造函数创建一个新的Point实例 - this.center = new Point2D(center.getX(), center.getY());,而不是保持对传递给它的实例的引用。这意味着如果稍后修改了传递的center,则更改不会影响Circle实例。

第二个构造函数通常更安全,因为它有一个真正的私有Point实例作为Circle的中心,而第一个构造函数与构造函数的调用者共享center

您可以看到与此代码的区别:

Point2D point = new Point2D(10.0, 20.0);
Circle circle = new Circle (point, 4.0);
point.setX (5.0);
System.out.println(circle); // assuming you override toString to display the properties
                            // of the Circle

如果使用第一个构造函数,执行此代码后,您的圆将具有(5.0,20.0)的中心,而如果使用第二个构造函数,则圆的中心将为(10.0,20.0);

答案 2 :(得分:0)

Point2D不是不可变的,即具有可在构造点之后更改的属性。

Circle的第一个构造函数只使用Point2D对象 - 现在调用者可以更改也会影响圆的点对象。

Circle的第二个构造函数生成Point2D对象的副本。如果圆圈保持点对象的私密性,则无法从外部更改。

答案 3 :(得分:0)

this.center = center,您使用center对象的参数。

this.center = new Point2D(center.getX(), center.getY()),您使用参数Point2D创建center对象。