防御性复制和使用clone()

时间:2015-03-09 19:16:28

标签: java

我还处于学习java的早期阶段,并且很难掌握防御性复制,界面和不变性。

对于后台...我创建了一个不可变的RegisterNumber类,并使用对象工厂(getInstance()方法)生成随机ID。仅供参考 - 我有另一个名为IdentificationNumber的类,它具有类似的用途和方法(即通过对象工厂实例化,唯一值),但ID的格式不同。

注册号码与个人相关联 - 有1个/人,每个人都是唯一的。为此,我有一个Person接口,然后我有一个实现常见行为的Abstract Class AbstractPerson,以及两个扩展AbstractPerson的子类:男性和女性。这是无法改变的。

当我实例化Person时,我必须将它们与唯一的引用号相关联。 e.g。

AbstractPerson() {

            this.registration = RegistrationNumber.getInstance();

}

我的getInstance()方法如下(fyi - 它仍需要一些考虑,我理解它有缺陷,但我还处于早期阶段):

   private static final Map<String, RegistrationNumber> REG = new HashMap<String, RegistrationNumber>();  

   public static final RegistrationNumber getInstance() {
   //allow for possibility of limit being reached.

   Random r = new Random();

   int numbers = r.nextInt(9000) + 1000;

   Character letter = (char)(r.nextInt(26) + 'a');

   String strRep = letter + "" + numbers;

   RegistrationNumber n = REG.get(strRep);

   if (n == null) {

       n = new RegistrationNumber(numbers, letter, strRep);

       REG.put(strRep, n);

    }

       return n;
    }

我的AbstractPerson类中必须有一个accessor方法,它返回唯一的引用号,而不允许它被修改。

我无法返回一个新对象,因为这会生成一个新的唯一编号,所以我可以使用.clone()克隆它,如下所示:

 final RegistrationNumber getRegistration() {

    return (RegistrationNumber) registration.clone();

    }

但那给了我一个错误.....&#34;克隆在java.lang.Object中保护了访问权限&#34;

我可以更改RegistrationNumber类中的getInstance()方法,因此它将RegistrationNumber作为参数,然后当我调用getRegistration()时,我可以检查该数字是否存在并返回它是否存在?但是当我第一次调用getInstance()时会发生什么?如何在实例化之前传递自身的参数?!

这是针对学校的,所以请不要给出代码 - 只是在正确的方向上轻推,否则澄清会有所帮助。

帮助?? !!

2 个答案:

答案 0 :(得分:0)

听起来像想要的是一种从现有RegistrationNumber创建RegistrationNumber的方法。

例如,您可以将RegistrationNumber实现为Cloneable,并覆盖clone()方法。

我不明白为什么您认为需要 AbstractPerson在返回时克隆RegistrationNumber。如果它是不可变的,只需返回实际对象。

答案 1 :(得分:0)

如果没有看到完整的代码,就无法确定,但是你可以在这里犯下的两个明显错误就是将注册对象声明为Object的实例,如:

private Object registration;

在您的AbstractPerson类中。如果是这种情况,请将其更改为

private RegistrationNumber registration;

或在调用clone之前向下转发:

return (RegistrationNumber)(((RegistrationNumber)registration).clone());

或者你还没有在RegistrationNumber课程中实现克隆。在这种情况下,忽略以上所有内容并实现它。

另一方面,我认为您使用单例模式生成RegistrationNumbers。拥有一个单例生成器以便它可以像你的情况一样保存已生成的数字,这很好,但getInstance()应该是给你单例实例的方法,而不是注册号。我建议你和老师讨论这个想法。