4
class A
{
    B b;
    public A()
    {
        b = new B(this);
        //initialization of class A variables
    }

    public void meth1()
    {

    }
}

class B
{
    A a;
    public B(A a)
    {
        this.a = a;
    }
}

I know that this reference shouldn't be passed in this way,but what happens if this is done

Some other class calls the class A constructor. when is the "this" reference actually allocated memory? would it be assigned memory as soon as A's constructor is called before even super() is called.

Suppose class B is a thread and since B has A's reference can B call the methods on A before A's constructor doesn't even return if "this" reference is not allocated memory yet.

vjk
  • 2,163
  • 6
  • 28
  • 42
  • 1
    _I know that this reference shouldn't be passed in this way_ It can be passed just as you did. – Sotirios Delimanolis Mar 21 '13 at 16:00
  • _I know that this reference shouldn't be passed in this way_ why not ? – Simeon Mar 21 '13 at 16:00
  • i meant its not a good practice – vjk Mar 21 '13 at 16:01
  • why ? where did you read it and what are the arguments against its usage ? – Simeon Mar 21 '13 at 16:01
  • http://www.ibm.com/developerworks/java/library/j-jtp0618/index.html – vjk Mar 21 '13 at 16:03
  • @Simeon: he's right. It's not a good idea to do that. Only fully constructed objects should be passed around. – Joachim Sauer Mar 21 '13 at 16:04
  • @SotiriosDelimanolis It shouldn't as it is not fully constructed yet. His phrase about *not passing it this way* was solely meant within constructors and not in general. – brimborium Mar 21 '13 at 16:08
  • 1
    @brimborium I agree with you if the object is going to be manipulated, but in his example he is just assigning it to an instance variable so no big deal. – Sotirios Delimanolis Mar 21 '13 at 16:45
  • @SotiriosDelimanolis I think this is mainly a matter of taste. I wouldn't do it that way, but you are right, it should be harmless in this simple case. However, if there is more code around it, it may not be easy to see potential problems. – brimborium Mar 26 '13 at 08:48

5 Answers5

3

The memory for the object is allocated before any constructor is executed. Otherwise the constructor would have not place to write the values of the variables.

Therefore you can pass out a reference to the current object (a.k.a this) to other pieces of code inside the constructor.

As you noted, the object is not fully constructed at that time and it's a bad idea to actually do that, but "just" because the values of the object can be in an inconsistent state. The memory is already allocated and reserved for that object at this point in time.

this is just a reference to the "current object", which you could think of as just another parameter that any non-static method gets. In fact in that's actually how the JVM treats it. See JVMS §2.6.1 Local Variables:

On instance method invocation, local variable 0 is always used to pass a reference to the object on which the instance method is being invoked (this in the Java programming language).

So the direct answer to "when is this allocated" is effectively: Whenever you call a method on an object.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • what is "this" reference actually, is it a variable created by the jvm for each class? – vjk Mar 21 '13 at 16:12
1

this refers to current object and any object is allocated memory using "new"

enigma
  • 89
  • 6
0

The memory is allocated when JVM is processing new instruction. If for example your code looks like:

A a = new A();
      ^
      here the memory for A is allocated

It indeed could be a problem to pass this to B. Constructor of B can invoke instance method of A before the constructor of A has been finished. You should move line to the end of constructor of A to avoid possible problems. Alternatively you could manage the object lifecycle from outside using setters.

AlexR
  • 114,158
  • 16
  • 130
  • 208
  • A is allocated memory when new is called, but when is this memory location assigned to "this" – vjk Mar 21 '13 at 16:10
0

this is assigned before the constructor is called. In fact, the super() call is not necessary. It only ensures that the creation stuff of the parent class is done, which doesn't matter if the parent class is Object. Also, A's methods are usable as soon as the object is created (even before the constructor is called) so if B got the reference to A in the constructor, it can use A's methods just like A itself in the constructor. Just be sure to make A's methods so that they can be used when A is not fully initialized, or just create and start B after the initialization is complete.

PurkkaKoodari
  • 6,703
  • 6
  • 37
  • 58
0

As long as you don't modify A or call methods on A or it's members in the constructor of B it will work. ( See other answers)

If you call a method on an not completely initialized object (after construction) it's not defined what happens. Especially if you use multiple threads (see memory barrier).

More on this topic: How do JVM's implicit memory barriers behave when chaining constructors?

Community
  • 1
  • 1
helios
  • 339
  • 2
  • 4