1

I got two classes.

  • busiObj(created from ancient flat files)
  • key(provides means to tell busiObjs apart)

key has a c'tor that takes a busiObj

public key(busiObj foo)
{
    bar = foo.someThing;
    [...]
}

I want to create the key in the c'tor of the busiObj

public busiObj(...)
{
    myKey = new key(this);
    [...]
}

However: Why on earth does it work?
I firmly expected the compiler to throw something like:
"You cannot reference an object that is currently being made, duh".

So: How is it that I can reference an object while it is still being constructed?

  • 2
    The object might not be finished being constructed, but we know where it will be (in memory) when it is, hence we can get a reference to that location. – George Duckett Jul 1 '14 at 7:30
  • @GeorgeDuckett then is it safe to do this call, given that I initialized all parts of myObj that the c'tor of key uses? Also: Is this bad practice (it somehow feels so)? – Mark Jul 1 '14 at 7:33
3

So: How is it that I can reference an object while it is still being constructed?

Presumably Because it's useful (though in a dangerous way) for exactly the scenario you describe, so the language designers decided to allow it.

Technically, it's not a problem at all: while the object is being constructed, its memory must already be allocated, so you can certainly have a reference to it.

  • Just as @George Duckett also lines out. It feels wrong though. – Mark Jul 1 '14 at 7:35
  • 4
    @Mark: It's safe to do inasmuch as there is no undefined behaviour; the worst you can encounter (if you make a mistake) is object states (mostly null references) that are not possible according to your class contract. It's not a good practice because in maintaining that code, it's easy to lose track of the fact that you're handling a partially initialized object and introduce weird bugs. – Michael Borgwardt Jul 1 '14 at 7:46
  • Instantiate an object without a constructor is intriguing. It means an object exists before the constructor is called. – radarbob Jul 4 '14 at 1:28
1

Why this happens is because this is a reference to the memory area that your object is currently occupying. Since instructions in the code are executed sequentially, you already have your object in some state that's being referenced when you get to the point of calling the key() method.

Although this is possible, the entire approach is wrong. The methods inside an object should only change the state of the instance, not the state of other instances of that object. Your example works because it roughly translates into the code below at runtime:

public busiObj() { 
    myKey = new key();
    [...]
}

public key()
{
    bar = foo.someThing;
    [... use "this" here to reference your object internally ...]
    [... other stuff here ...]
}
  • ...not the state of other instances of that object where am I doing that? I am not changing one busiObj from another. – Mark Jul 1 '14 at 8:37
  • In your implementation the key() method gets a busiObj object as a parameter - but you're under no obligation to send the current instance to the method. Assuming you work on the foo object that you get, if that object is not this then you will essentially work in your method with another object. Since you are sending the this reference from the constructor, the interpreter takes care of translating the reference to your current object in key(), but this will not alwais be the case. – Thyamarkos Jul 1 '14 at 8:40
  • ahh, that's what you mean. I am actually reading already initialized properties from the passed, half-finished busiObj, not manipulating its state though. – Mark Jul 1 '14 at 8:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.