Java:将“this”作为构造函数参数传递以引用创建对象的替代方法

时间:2012-12-24 16:59:47

标签: java constructor this

我已经花了一段时间考虑我所读过的那个解决方案(我还没有真正熟悉Java),使用它来构造函数参数通常不是一个好习惯。

我想要做的是实例化JobGroupMod类的几个对象,并且对于每个JobGroupMod,我必须创建一定数量的JobMod对象,这些对象必须能够引用它们已经从中生成的JobGroupMod对象。

为了实现这一目标,我将“this”传递给JobMod构造函数,但即使工作,也感觉不适合设计。

public class JobGroupMod implements JobGroup {

    public JobGroupMod(Node n,Set<Job> clusterJobs){
        JobMod j=new JobMod(n,this);
    }
}

现在是JobMod类:

public class JobMod implements Job {
     public JobMod(Node n, JobGroup jg){
         setJobGroup(jg);
     }
}

我的问题是,有没有更好的方法来解决这个问题,或者我的解决方案是建议的方式?

3 个答案:

答案 0 :(得分:7)

您应该尝试使用静态工厂方法(Effective Java link)。

这样就可以避免在构造函数调用中传递this,至少可以说这是非常不明智的。
示例代码:

public class JobGroupMod implements JobGroup {

    public static JobGroupMod createModeMod(Node n, Set<Job> clusterJobs) {
        JobGroup jg = new JobGroupMod();
        JobMod j = new JobMod(n, jg);
        return jg;
    }
}

答案 1 :(得分:5)

只要你理解其后果,只要你在JobGroupMod构造函数中做的唯一事情就是相当安全。现实世界中有很多Java代码可以做到这一点。它仍然不是你真正想做的事情,特别是当你开始谈论多线程和并发时。

在完全构造对象之前,危险就是将this传递给其他东西。如果构造函数在执行此操作后抛出异常并且未完全构造,则可能会出现令人讨厌的问题。如果另一个线程在完全构造之前访问了您传递this的对象,那么您将遇到一个令人讨厌的问题。

您经常在Java中找到的是使用工厂模式来避免这种情况的人,“init”类型方法或依赖注入。

答案 2 :(得分:0)

一般来说没有魔力。您可以通过构造函数传递参数,也可以稍后使用setter / init方法将其初始化。

如果您的班级JobMod需要引用JobGroupMod而且没有任何关系,请使用构造函数传递它。如果有时它可以不用它创建init()方法或设置器,可以初始化此引用。

BTW有时您必须创建参数化和默认构造函数:第一个用于常规编程用法,第二个用于使用XML,JSON或其他序列化,这对于类似bean的类更容易。在这种情况下,至少创建javadoc,解释不应该直接使用默认构造函数。