假设您有一个类Dog
,它有
public class Dog {
private String name;
private double age;
// some setters
// some getters
此外,您有一个班级DogHandler
,它会生成Dog d
的一个实例并将其传递给Owner
我想,我可以
...在将狗传递给Owner
之前制作一份狗的副本,但这是一项昂贵的操作,我宁愿避免使用它。
...提出Dog
实现的接口,其中仅包含getter,将Dog
强制转换为该接口并传递结果
...在构造函数中初始化可设置变量,并且根本不允许更改此对象实例
还有其他方法可以确保对象的接收者无法修改它吗?
如何获取包含某些数据的简单bean并将其设为只读?
答案 0 :(得分:2)
这可以通过几种方式实现,我可以向你提出其中两种:
a)与getter的接口是个好主意
b)从Dog创建派生类,其中setter方法被阻止,如下所示:
class UnmodifiedDog extends Dog {
public UnmodifiedDog(double age, String name) {
super.setAge(age);
super.setName(name);
}
@Override
public void setAge(double age) {
throw new UnsupportedOperationException();
}
@Override
public void setName(String name) {
throw new UnsupportedOperationException();
}
}
在DogHandler:
Dog createDog() {
return new UnmodifiedDog(10, "Fido");
}
您可以将此传递给所有者:
owner.receiveDog(dogHandler.createDog());
答案 1 :(得分:0)
您在问题中提到的方法几乎是使Dog
不可变的标准步骤。唯一的另一个提示是强制要求Dog
无法通过将类声明为final
来覆盖。
答案 2 :(得分:0)
在此处提到的解决方案中,您还可以利用可见性修饰符。如果Dog
和Owner
位于不同的包中,则可以将mutator的可见性设置为默认(包)范围或受保护的范围。
这将允许您将Dog
和DogHandler
保留在同一个包中(因此允许它们相应地改变Dog
对象),同时保留Owner
个对象分开(因此阻止他们对Dog
个对象进行任何修改。)
答案 3 :(得分:0)
以下是使用接口和包访问设置器的示例。
package blah.animal;
public interface Dog
{
double getAge();
String getName();
}
package blah.animal;
public class DogImpl implements Dog
{
private double age; // double seems wrong for age.
private String name;
... getters (defined by Dog interface)
// package access setters.
void setAge(double newValue)
{
age = newValue;
}
void setName(String newValue)
{
name = newValue;
}
package blah.animal;
public class DogHandler
{
public static Dog newDog(double age, String name)
{
Dog returnValue = new DogImpl();
returnValue.setAge(age);
returnValue.setName(name);
return returnValue;
}
}
package.blah.somethingelse;
public class Blam
{
private Dog myDog;
public Blam()
{
myDog = DogHandler.newDog(1.4D, "Tippy");
}
}