“this”关键字在初始化程序块中的含义是什么?

时间:2014-03-08 06:41:24

标签: java this

这是我的代码:

class StaticBlock {
    {       
        println("initializer block : " + message);
    }
    public StaticBlock(String message) {
        this.message = message;
    }
    private String message;
}

现在的问题是,在初始化程序块

{       
    println("initializer block : " + message);
}

如果我在this之前添加message关键字,则可行,但错误this关键字时会出错。

编译器说:

StaticBlockDemo.java:34: illegal forward reference
                println("initializer block : " + message);
                                                 ^
1 error

为什么他们不一样?

4 个答案:

答案 0 :(得分:5)

我不知道设计原理,但它可能有助于阅读Java语言规范的相关部分。

8.6. Instance Initializers

  

允许实例初始值设定项通过关键字this(第15.8.3节)引用当前对象,以使用关键字super(§15.11.2,§15.12),并使用范围内的任何类型变量。

     

使用在使用后以声明方式显示声明的实例变量有时会受到限制,即使这些实例变量在范围内也是如此。有关控制实例变量的正向引用的精确规则,请参见§8.3.2.3。

8.3.2.3. Restrictions on the use of Fields during Initialization

  

成员声明只有在成员是类或接口static的实例(分别为C)字段并且满足以下所有条件时才需要以文本方式显示:

     
      
  • 用法发生在static的实例(分别为C)变量初始值设定项或C的实例(分别为静态)初始值设定项中。

  •   
  • 用法不在作业的左侧。

  •   
  • 用法是通过一个简单的名称。

  •   
  • C是封闭用法的最内层的类或接口。

  •   

以下是修剪规范部分的示例,以说明您所询问的具体问题:

class UseBeforeDeclaration {

    {
        j = 200;
          // ok - assignment
        j = j + 1;
          // error - right hand side reads before declaration
        int k = j = j + 1;
          // error - illegal forward reference to j
        int n = j = 300;
          // ok - j at left hand side of assignment
        int h = j++;
          // error - read before declaration
        int l = this.j * 3;
          // ok - not accessed via simple name
    }

    int j;
}
但是,我应该注意,即使是代码的编译版本也不会做你想要的。如果你运行它:

new StaticBlock("abc");

会打印

initializer block : null

这是因为初始化程序在构造函数体之前(大部分)执行。以下是规范中的重点:

12.5. Creation of New Class Instances

  

[...] 处理指示的构造函数以使用以下过程初始化新对象:

     

[...]

     

4.为此类执行实例初始值设定项和实例变量初始值设定项 [...]

     

5.执行此构造函数的其余部分。 [...]

答案 1 :(得分:0)

  

如果我在'message'之前添加'this'关键字,它可以正常工作,但在错过'this'关键字时会出错。为什么他们不一样?

this个关键字指向该类的当前实例。

public StaticBlock(String message) {
    this.message = message;
}

如果您不使用this,那么它将分配message局部变量的值,因为局部变量的范围大于块中的实例。

当您使用this时,它将分配当前对象变量的变量值。

答案 2 :(得分:0)

如果局部变量名和实例成员名之间存在冲突,那么编译器将this关键字告诉使用对象变量。

答案 3 :(得分:0)

在Java中使用类的一个好处是,您可以将对象建模为类,并且可以创建对象的多个实例(在大多数情况下)。

为了引用特定于单个对象类的信息,我们可以在对象(类)代码中使用this。它告诉程序您要使用current个对象变量和值。通过使用this.message = message,您将分配已传递给函数的消息值并将其存储在对象的消息变量中。

这有范围方面,其中message具有局部范围,this.message具有整个对象的范围。这就是为什么当您尝试在打印代码中调用消息时println("initializer block : " + message);,在此函数的范围内不存在本地变量消息。