Java 什么是;这";初始化程序块中的关键字平均值?

Java 什么是;这";初始化程序块中的关键字平均值?,java,this,Java,This,这是我的密码: class StaticBlock { { println("initializer block : " + message); } public StaticBlock(String message) { this.message = message; } private String message; } 现在的问题是,在初始化程序块中 { println("init

这是我的密码:

class StaticBlock {
    {       
        println("initializer block : " + message);
    }
    public StaticBlock(String message) {
        this.message = message;
    }
    private String message;
}
现在的问题是,在初始化程序块中

{       
    println("initializer block : " + message);
}
如果我在
消息
之前添加
关键字,它会工作,但缺少
关键字时会出错

编译器说:

StaticBlockDemo.java:34: illegal forward reference
                println("initializer block : " + message);
                                                 ^
1 error
为什么它们不一样

如果我在“message”之前添加“this”关键字,它会工作,但在缺少“this”关键字时会出错。为什么它们不一样

这个
关键字指向类的当前实例

public StaticBlock(String message) {
    this.message = message;
}
在这里,如果您不使用
this
,那么它将分配
message
局部变量的值,因为局部变量的范围大于块中的实例


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

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

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

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


这有一些作用域方面,其中
message
具有局部作用域,而
this.message
具有整个对象的作用域。这就是为什么当您试图调用打印代码中的消息时:
println(“初始值设定项块:+message”),此函数范围内不存在局部变量消息。

我不知道设计原理,但阅读Java语言规范的相关章节可能会有所帮助

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

即使这些实例变量在作用域中,但在使用后以文本形式显示其声明的实例变量的使用有时会受到限制。有关实例变量正向引用的精确规则,请参见§8.3.2.3

仅当成员是类或接口
C
的实例(分别为
static
)字段且满足以下所有条件时,成员声明才需要在使用前以文本形式出现:

  • 该用法出现在
    C
    的实例(分别为
    static
    )变量初始值设定项或
    C
    的实例(分别为static)初始值设定项中

  • 用法不在作业的左侧

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

  • 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
这是因为初始值设定项在构造函数主体之前执行(大部分)。以下是规范中的要点:

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

[……]

四,。为此类[…]执行实例初始值设定项和实例变量初始值设定项

五,。执行此构造函数主体的其余部分。[……]


“this”,我可能是指“current”实例,但在这里,它似乎让我感到困惑。那些“重复”实际上不是同一个问题,如果您阅读的内容超过摘要……我同意,这些重复实际上不是重复的。“class variable”?它不应该是“实例变量”吗?我很困惑,因为在非静态方法中,“this”是否存在都是一样的,我的意思是,它不是必需的,不是吗?是的,你是对的,变量属于对象。在堆栈中,语句“StaticBlock(String message)”确实创建了一个变量“message”,不是吗?让我困惑的是,在常见的非静态方法中,即使不使用“this”,我们也可以引用实例变量。您不认为它们不相似吗?如果您不使用this,它将创建名为
message
的局部变量,此处将为同一局部变量指定相同的值。“让我困惑的是,在常见的非静态方法中,即使不使用‘this’,我们也可以引用实例变量。您不认为它们不相似吗?”--可以,但必须使用不同的局部变量和实例变量名称。这里有两个相同的
消息
谢谢,实际上,你是对的,我在范围初始值设定项块外定义了实例变量“message”,除非我使用关键字“this”,否则它是无法访问的。谢谢,实际上,你是对的,我在作用域初始值设定项块外定义了实例变量“message”,除非我使用关键字“this”,否则它是不可访问的。