Java: Alternative to passing “this” as constructor

2019-03-26 04:32发布

I've spent a while thinking about different solutions that the one I went for as I've read around (I am not really experienced with Java yet) that using this for a constructor argument isn't usually a good practice.

What I am trying to do is to instantiate several objects of class JobGroupMod and for every JobGroupMod I have to create a certain number of JobMod objects that must be able to reference back the JobGroupMod objects in which they've been spawned from.

In order to accomplish that I am passing "this" to the JobMod constructor but, even if working, it didn't feel like proper designing.

public class JobGroupMod implements JobGroup {

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

And now the JobMod class:

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

My question is, is there a better way of solving this, or is my solution the suggested way?

3条回答
劫难
2楼-- · 2019-03-26 04:58

You should try using a static factory method (Effective Java link).

This way you avoid passing this in a constructor call, which is highly ill-advised to say the least.
example code:

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;
    }
}
查看更多
闹够了就滚
3楼-- · 2019-03-26 04:59

As long as it remains the only thing you do in the JobGroupMod constructor is is fairly safe as long as you understand the ramifications. There's a lot of Java code in the real world that does this. It's still not something you really want to do, especially when you start talking about multithreading and concurrency.

The danger is passing this to something else before an object is fully constructed. If the constructor were to throw an exception after you did this and not fully construct, you could have a nasty problem. If another thread were to access the object you passed this to before it was fully constructed, you'd have a nasty problem.

What you'll often find in Java is people using a factory pattern to avoid this, an "init" type method, or dependency injection.

查看更多
Root(大扎)
4楼-- · 2019-03-26 05:07

Generally there is no magic. You can either pass parameter via constructor or initalize it later using setter/init method etc.

If your class JobMod needs reference to JobGroupMod and has nothing to do without it pass it using constructor. If sometimes it can stand without it create init() method or setter that can initialize this reference.

BTW sometimes you have to create both parameterized and default constructor: first for regular programmatic usage, second if you are using XML, JSON or other serialization that is going easier for bean-like classes. In this case at least create javadoc that explains that default constructor should not be used directly.

查看更多
登录 后发表回答