【问题标题】:How to force java object to instantiate it's instance variables in specific order?如何强制java对象以特定顺序实例化它的实例变量?
【发布时间】:2017-03-19 21:08:24
【问题描述】:

上课:

class Test {

  Object1 object1;
  Object2 object2;

  void setObject2 (Object2 newObject) {
    if (object1.someMethod()) {
      this.object2 = newObject;
    } else {
      someOtherMethod();
    }
  }
}

如何强制object1 必须在object2 之前实例化的对象实例化?

现在我可以想办法解决它

1.通过以Object2为参数的构造函数并在那里实例化它

Test(Object1 object1) {
  this.object1 = object1;
}

2.通过尝试设置object2的方法抛出异常

void setObject2 (Object newObject) {
  if (object1 == null) {
    throw new Exception();
  }
  ...

还有其他更合适的方式来实现吗?

我需要它的原因是我必须为区域object1 创建新的广告活动Test 来宣传该区域的一些网站object2。在我可以将网站添加到广告系列之前,我想检查该网站是否属于该地区。

【问题讨论】:

  • 请问你的目的是什么?
  • @acornagl 你在问我吗?
  • @ItamarGreen 不,很抱歉我要问 Marcin,但 @ 出了点问题
  • @acornagl 我必须为一个地区创建新的广告活动来宣传该地区的一些网站。在将网站添加到广告系列之前,我想检查该网站是否属于该地区。
  • @MarcinKruglik 我明白了。

标签: java oop instance-variables


【解决方案1】:

一种更简洁的设计方式是使用 Builder 模式。这样您就可以仅以正确的方式设置和创建对象,而不是在运行时获取异常。

程序员不需要阅读文档或错误消息来找出他需要做什么,因为 API 自己做“指导”。

【讨论】:

  • 实际上,我在我的真实代码中使用了Builder-pattern。我试图使我的问题笼统,而不是绑定到特定情况。即使我使用构建器,我也需要使用一些算法来检查实例变量是否以正确的顺序实例化。
【解决方案2】:

您可以限制object2 的初始化,使其只有在object 已经被实例化时才能被实例化。

public void setObject2 (Object2 newObject) {
    if(object1 == null){ 
        throw new IllegalStateException();
    }else{
        this.object2 = newObject;
    }
}

【讨论】:

  • 以上是正确的,另外该方法可能会抛出 java.lang.IllegalStateException,因此该类的工作人员知道有些事情已经搞砸了。 IllegalStateException:表示方法已在非法或不适当的时间被调用。换言之,Java 环境或 Java 应用程序未处于请求操作的适当状态。
  • 这是个坏主意,因为调用者无法知道对 setter 的调用没有任何效果。
  • @Bohemian 修复它。实现 srinath 的想法
  • @ItamarGreen 或者你可以让它返回一个布尔值来指示操作是否成功结束。
  • @aleb2000 不需要,如果用户收到异常,他们就知道出了什么问题
【解决方案3】:

是的,将变量初始化为适当的状态应该使用构造函数来完成,您实际上可以创建一个Test class constructor 来实现相同的效果,如下所示:

public Test(Object1 obj1, Object2 obj2) {
    //if objects are null throw an error
    if(obj1 == null) {
       throw IllegalStateException("Invalid Object1 passed");
    } else {
      this.obj1 = obj1;
     //check someMethod() returns true and then set object2
     if (obj1.someMethod()) {
      this.obj2 = obj2;
     } else {
       //obj1.someMethod() is false, call someOtherMethod()
       someOtherMethod();
    }
  }

如果强制变量状态未正确初始化,则最好从构造函数中抛出Exception(如上),以便对象在创建后不会处于不一致状态。

【讨论】:

  • 如果使用你的构造函数,那么异常会一直抛出(obj1总是null)
  • 为什么 obj1 总是为空?
  • 对不起,我以为你指的是this.obj1
猜你喜欢
  • 2011-01-10
  • 2020-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-29
  • 1970-01-01
  • 2019-08-07
相关资源
最近更新 更多