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;
    }
}

我知道这个引用不应该以这种方式传递,但是如果这样做会发生什么

其他一些类调用类 A 构造函数。“this”引用何时实际分配内存?只要在调用 super() 之前调用 A 的构造函数,它会被分配内存吗?

假设 B 类是一个线程,并且由于 B 具有 A 的引用,如果“this”引用尚未分配内存,B 可以在 A 的构造函数甚至不返回之前调用 A 上的方法。

4

5 回答 5

3

在执行任何构造函数之前为对象分配内存。否则构造函数将没有地方写入变量的值。

因此,您可以将对当前对象(又名)的引用传递给this构造函数内的其他代码段。

正如您所指出的,当时对象还没有完全构造,实际上这样做是一个坏主意,但是“只是”因为对象的可能处于不一致的状态。此时已为该对象分配和保留内存。

this只是对“当前对象”的引用,您可以将其视为任何非静态方法获取的另一个参数。事实上,这实际上是 JVM 对待它的方式。请参阅JVMS §2.6.1 局部变量

在实例方法调用时,局部变量0始终用于传递对正在调用实例方法的对象的引用(this在 Java 编程语言中)。

因此,“何时this分配”的直接答案是有效的:每当您在对象上调用方法时。

于 2013-03-21T16:03:27.000 回答
1

this 指的是当前对象,并且任何对象都使用“new”分配内存

于 2013-03-21T16:21:02.240 回答
0

只要您不修改A或调用方法,A或者它的构造函数中的成员B就可以工作。(见其他答案)

如果您在未完全初始化的对象上调用方法(在构造之后),则未定义会发生什么。特别是如果您使用多个线程(请参阅内存屏障)。

有关此主题的更多信息: 链接构造函数时 JVM 的隐式内存屏障如何表现?

于 2013-03-21T16:14:46.233 回答
0

this在调用构造函数之前赋值。事实上,super()调用是没有必要的。它只是确保父类的创建东西已经完成,如果父类是Object. 此外,A 的方法在创建对象后立即可用(甚至在调用构造函数之前),因此如果 B 在构造函数中获得对 A 的引用,它可以像在构造函数中使用 A 本身一样使用 A 的方法。只要确保 A 的方法可以在 A 未完全初始化时使用,或者在初始化完成后创建并启动 B。

于 2013-03-21T16:05:58.933 回答
0

内存是在 JVM 处理new指令时分配的。例如,如果您的代码如下所示:

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

this传递给确实可能是个问题B。的构造函数可以在构造函数完成之前B调用实例方法。您应该将行移动到构造函数的末尾以避免可能出现的问题。或者,您可以使用 setter 从外部管理对象生命周期。AAA

于 2013-03-21T16:05:40.190 回答