使用"这个"初始化实例变量时,它引用了哪个对象以及它是如何工作的?

时间:2015-07-26 14:30:39

标签: java

在将此标记为重复之前,请先阅读一次问题。我已经从here已经阅读了与this相关的问题。

我有两个java类Test2和Test,如下所示。据我所知this引用当前对象,可以在constructorsnon-static methods内以及其他问题(上面给出的链接)中给出的其他各个地方使用。但是当我使用this初始化Test2中的实例变量时:

  1. 它指的是哪个对象,如果它引用当前的调用对象,为什么它不打印Hello World!
  2. 如果没有,那么这里引用的是哪个对象以及如何将其传递给实例变量?
  3. Class Test2.java

    public class Test2 {
    
      private String test2Str;
      private Test test = new Test(this);//Please notice the instance variable init
    
      public Test2(String str){
        this.test2Str = str;
      }
    
      public Test getTest() {
        return test;
      }
    
      public String getStr() {
        return this.test2Str;
      }
    
      public void setTest(Test test) {
        this.test = test;
      }
    
      public static void main(String[] args){
        Test2 object = new Test2("Hello World!");
    
        String thisStr = object.getTest().getStr();
    
        System.out.println(thisStr);
    
     }
    }
    

    Class Test.java

    public class Test {
    
       String str;
    
       public Test(Test2 test){
    
            System.out.println(test);
    
            System.out.println(test.getStr());
    
            str = test.getStr();
       }
    
       public void setStr(String str){
            this.str = str;
       }
    
       public String getStr(){
            return this.str;
       }
    }
    

    该计划的第一次输出:

    com.avnet.spoj.lifeuniverse.Test2@56e5b723
    null
    null
    

    注意:如果我在构造函数中移动实例变量初始化,如下所示。它按预期工作,我可以理解。有人可以解释this的上述行为吗?

    private String test2Str;
    private Test test = null;
    
    
    public Test2(String str){
        this.test2Str = str;
        test = new Test(this); 
    }
    

    该计划的第二次输出:

    com.avnet.spoj.lifeuniverse.Test2@56e5b723
    Hello World!
    Hello World!
    

3 个答案:

答案 0 :(得分:3)

您的第一个代码段中的代码:

private String test2Str;
private Test test = new Test(this);//Please notice the instance variable init

public Test2(String str){
    this.test2Str = str;
}

相当于

private String test2Str = null;
private Test test = null;

public Test2(String str){
    test = new Test(this);
    this.test2Str = str;
}

因此,当调用new Test(this)时,this是正在构造的Test2实例,但在调用时,this.test2Str = str尚未执行,并且是test2Str因此是空的。这就是你看到

的原因
null
null

正在打印。

在您的第二个示例中,{/ 1}}在执行 new Test(this)后被称为,这就是您看到的原因

this.test2Str = str

正在打印。

你应该避免从构造函数中将Hello World! Hello World! 泄露给外部对象,甚至是可覆盖的方法:这些外部对象将看到一个部分构造的对象,因此不会尊重它的不变量。

答案 1 :(得分:1)

从这个答案this

在构造函数体之前执行初始化器。 (如果您同时拥有初始化器和构造函数,则构造函数执行第二个并覆盖初始化值,这会产生影响。)

答案 2 :(得分:0)

for loop指的是它出现的类的“当前实例”,但在初始化期间使用它作为第一个示例是部分未定义的。该代码在构造函数运行之前运行;在构造函数完成之前引用变量实例的任何内容都必须被视为可疑。这至少是糟糕的编码实践。