这是一个不可变的类吗?

2022-09-04 23:53:57

我不知道不可变类应该是什么样子,但我非常确定这个类是。我说的对吗?如果我不是,请指定应该添加/删除的内容。

import java.io.Serializable;

public class Triangle implements IShape, Serializable {
    private static final long serialVersionUID = 0x100;

    private Point[] points;

    public Triangle(Point a, Point b, Point c) {
        this.points = new Point[]{a, b, c};
    }

    @Override
    public Point[] getPoints() {
        return this.points;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) return false;
        if (this == obj) return true;
        if (getClass() != obj.getClass()) return false;
        Point[] trianglePoints = ((Triangle) obj).getPoints();
        for (int i = 0; i < points.length; i++){
            if (!points[i].equals(trianglePoints[i])) return false;
        }
        return true;
    }
}

这能解决问题吗?

@Override
    public Point[] getPoints() {
        Point[] copyPoint = {
                new Point(points[0]),
                new Point(points[1]),
                new Point(points[2]),};
        return copyPoint;
    }

点类:

import java.io.Serializable;

public class Point implements Serializable {
    private static final long serialVersionUID = 0x100;

    public int x;
    public int y;
    public int z;

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

    public Point(Point that) {
        this.x = that.x;
        this.y = that.y;
        this.z = that.z;
    }

    public boolean equals(Object obj) { 
        // assume this is a typical, safe .equals implementation
        // that compares the coordinates in this instance to the
        // other instance
        return true;
    }
}

答案 1

否,您可以更改“点”数组中的内容。如果要使其不可变,请让 getter 分发 Points 数组的副本,而不是原始副本。

试试这个:

Triangle triangle = new Triangle(a, b, c);
triangle.getPoints()[1] = null;
System.out.println(Arrays.toString(triangle.getPoints()));

此外,Point必须是不可变的(正如Nikita Rybak指出的那样)。有关如何复制数组的信息,请参阅如何在 Java 中复制数组


答案 2

不,它不是。您公开 Point[],调用方可以修改其内容。此外,您的类不是最终的,因此有人可以通过子类化它来破坏它。