【问题标题】:when is "this" assigned memory location and at what point can a method be called in java“this”是什么时候分配的内存位置,什么时候可以在java中调用一个方法
【发布时间】:2013-03-21 15:56:22
【问题描述】:
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 上的方法。

【问题讨论】:

  • 我知道这个引用不应该这样传递可以像你一样传递。
  • 我知道这个引用不应该这样传递为什么不呢?
  • 我的意思是这不是一个好习惯
  • 为什么?您在哪里读到它,反对使用它的论据是什么?
  • @brimborium 如果要操纵对象,我同意你的看法,但在他的示例中,他只是将其分配给实例变量,所以没什么大不了的。

标签: java


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 究竟什么是“this”引用,它是jvm为每个类创建的变量吗?
【解决方案2】:

this 引用当前对象,任何对象都使用“new”分配内存

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

    • A在调用new的时候被分配了内存,但是这个内存位置是什么时候分配给“this”的
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

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

      有关此主题的更多信息: How do JVM's implicit memory barriers behave when chaining constructors?

      【讨论】:

        猜你喜欢
        • 2014-03-27
        • 1970-01-01
        • 2012-05-16
        • 2018-01-01
        • 2015-01-22
        • 2011-09-19
        • 2011-02-24
        • 2019-07-12
        相关资源
        最近更新 更多