如果在 class 中正确设计了封装

If encapsulation is properly designed in the class

这个class封装是否设计合理?具有负高度和宽度值的示例对象实例可以存在还是不存在?

import java.awt.Dimension; 
/** * Example class. The x and y values should never * be negative. 
*/ 
public class Example { 
    private Dimension d = new Dimension (0, 0); 
    public Example () {} 
    /** * Set height and width. Both height and width must be nonnegative * or an exception is thrown. */ 
    public synchronized void setValues (int height, int width) throws IllegalArgumentException { 
        if (height < 0 || width < 0) throw new IllegalArgumentException(); 
        d.height = height; 
        d.width = width; 
    }

    public synchronized Dimension getValues() { // Passing member content by ref
        return d; 
    }
}

你不能强制执行。人们仍然可以通过您 return 在 getValues() 中的 Dimension 对象更改高度和宽度值,即使这违反了得墨忒耳定律。

Example example = new Example();
example.setValues(10, 5);
System.out.println(example.getValues()); // java.awt.Dimension[width=5,height=10]

Dimension dimension = example.getValues();
dimension.height = -1;
dimension.width = -1;
System.out.println(example.getValues()); // java.awt.Dimension[width=-1,height=-1]

来自文档: https://docs.oracle.com/javase/8/docs/api/java/awt/Dimension.html#width

public int width

The width dimension; negative values can be used.

为了克服这个问题,解决方案可能是 return 在 getValues() 中对 Dimension 对象进行深度克隆,以防止使用以下库更改原始对象: https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/SerializationUtils.html#clone(java.io.Serializable)

public synchronized Dimension getValues() { 
    return SerializationUtils.clone(d); 
    // OR return new Dimension(d.width, d.height);
}