Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing `this` as an argument during construction in java

Is it OK to pass this as an argument to a method while constructing an object in java?

Thinking about doing this makes me feel uneasy, but I'm not sure if it's definitely wrong. Take the following hypothetical example:

public final class A {
    private final B b;
    private final List<String> words;

    public A(B b) {
        this.b = b;
        words = new ArrayList<String>();
        for(int i = 0; i < 10; i++) {
            words.add(b.getNextStringFromUser(this));
        }
    }

    public List<String> getWords() {
        return words;
    }
}

public class B {
    // returns a String chosen by the user based on the current state of A
    public String getNextStringFromUser(A a) {
        List<String> wordsSoFar = a.getWords();
        // ... omitted
    }
}

The cases I can think of where doing this might be the right thing to do is where you want to construct an object which can be immutable from the point of view of the rest of your code, but where the constructor might take a different course depending on the state specified so far (if it makes sense to talk about the state of a partly constructed object). In the example above, a user chooses a string based on the strings chosen so far, and when they're all chosen, this object should never change again.

Is this sort of thing OK/advisable? Thanks.

like image 592
user1675642 Avatar asked Sep 13 '13 19:09

user1675642


2 Answers

Leaking the "this" reference in the constructor is dangerous, especially in a multithreaded environment. You may end up with not fully constructed object visible to other threads. It may behave ok if used from single thread, though, but bugs of this kind are realy hard to find and fix. So don't be surprised if your IDE will mark it as a warning.

like image 139
Jk1 Avatar answered Nov 09 '22 19:11

Jk1


The Java language is explicit about classes are constructed. See the spec here. If you are sure that the code you are calling is only accessing state that is initialized, then it is probably safe.

like image 41
fred02138 Avatar answered Nov 09 '22 17:11

fred02138