Is it not required to allocate memory explicitly using new before assigning value to data through a function call in java

StackOverflow https://stackoverflow.com/questions/20987951

Вопрос

There are three classes.

public class A
{
    private B b;
    private C c;

     public void abcMethod(){
        c = new C(this);
        b = c.xyzMethod(); // Doubt is here.
    }
}

public class B
{
    int i;
    public void setI( int i){
        this.i=i;
    }
    public int getI(){
        return i;   
    }         
}

public class C
{
     public B xyzMethod(){
        B b = new B();
        b.setI(10);
        return b;
    }
}

You may have noticed where my doubt is on the code. My question is- 1) why "new" is not required to allocate memory for the object b?

Probable answer: "Is it due to the reason that being a data member it has been already allocated memory while object of A got created."

2) Is my probable answer is correct? If its correct, why have we allocated memory to object c using new? Perhaps, its due the reason that "this" was to be passed to the object. So for proper initialization we used new with argument "this".

3) If I am correct at point 2 above, what does happen to the previously allocated memory to object c as new will allocate new chunk of memory and assign the new address to c? Garbage collected?

4) So from above points, we can say memory is allocated for the objects which are members of a containing class, at the time of object creation of the containing class. And we can directly assign value to them with out calling new on them?

[I am from C++ background, and this does not happen in C++. If a class is having pointer or reference to other class, we need to explicitly allocate memory for them.]

Please, correct me where I am wrong or something is missing in my understanding. Thanks and best regards.

Это было полезно?

Решение

1) why "new" is not required to allocate memory for the object b?

A new B is created by the method c.xyzMethod();

public B xyzMethod(){
    B b = new B();
    b.setI(10);
    return b;
}

As you can see a fully functional B is created by this method, memory allocated for it and a reference to it is passed. Object A is fully entitled to keep a reference to this object. There is no difference between this and both declaring a variable and initialising an object on a single line

2) Is my probable answer is correct? If its correct, why have we allocated memory to object c using new? Perhaps, its due the reason that "this" was to be passed to the object. So for proper initialization we used new with argument "this".

It is important to remember that object A does not need to allocate memory for object B, all class A needs is memory for a reference to object B. Object B can be kept elsewhere and many As can share the same B (although this isn't the case in your code)

3) If I am correct at point 2 above, what does happen to the previously allocated memory to object c as new will allocate new chunk of memory and assign the new address to c? Garbage collected?

Assuming there are no references to that object elsewhere (which is the case in your code) it will indeed become eligible to be garbage collected

4) So from above points, we can say memory is allocated for the objects which are members of a containing class, at the time of object creation of the containing class. And we can directly assign value to them we out calling new on them?

Although practically you can consider objects to "contain" other objects this is just a human way of looking at it. For example the following circular dependency is perfectly fine (although sometimes unwise):

public class A {
    private B b;

    public A() {
    }

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }

    public void main(String[] args){
        A a=new A();
        B b=new B();

        a.setB(b);
        b.setA(a);

        //because all that a and b contain is references this circular referencing
        //doesn't blow up

        //this line is stupid, but perfectly valid
        A referenceToAnA=b.getA().getB().getA().getB().getA();

    }

}

public class B {
    private A a;

    public B() {
    }

    public void setA(A a) {
        this.a = a;
    }

    public A getA() {
        return a;
    }


}

Final notes

Just like in C++ you must allocate memory for a new object by using the new keyword, it is however, not necessary to deallocate that memory, garbage collection deals with that

Другие советы

Thanks for the replies.Actually there was a misconception that is cleared out now. I was of the wrong notion that as the object b was created inside code of class C, we may need to use new again inside code of class A. But as pointed by @Richard Tingle, in A only there is reference and object can be created any where.

For this part:

[I am from C++ background, and this does not happen in C++. If a class is having pointer or reference to other class, we need to explicitly allocate memory for them.]

Again the behavior is similar in C++ also. We do not need to create the object "b" using "new" here because it has been created inside class C's method.Posted code for c++ below:

class B
{
    int i;
public:
    void setI(int i)
    {
        this->i=i;
    }
    int getI(){
        return i;   
    }         
};

class C
{
    int x;
public:
    B* returnB()
    {
        B *b = new B();
        b->setI(10);
        return b;
    }
};


class A
{
private:
    B *b;
    C *c;
public:
    B* getB(){
        return b;
    }
    void setB(B *b){
        this->b = b;
    }

    C* getC(){
        return c;
    }
};



int _tmain(int argc, _TCHAR* argv[])
{
    A *a = new A(); // allocates memory for reference to object of B & C

    C *c = new C(); // allocates memory for c
    B *b = c->returnB(); // for b memory is allocated inside the function
                         // so there is no need of a "new" here.
    a->setB(b);

    cout << "value of i is: " << a->getB()->getI() << endl; 
    return 0;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top