为什么以下编译
class Foo {
Object x;
String s = (String) x;
}
以下不编译?
class Foo {
Object x;
String s;
s = (String) x;
}
我错过了一些JLS
规则吗?我知道这一定是愚蠢的,但我仍然需要知道背后的原因。
答案 0 :(得分:2)
您可以使用实例级别块
{
s = (String) x;
}
赋值语句如果不属于声明语句,则应属于某个块。 块可以是任何东西(方法,构造函数等)
答案 1 :(得分:2)
non-static
块(此处标记为{ }
)可以访问variables
和methods
。在调用constructor
之后,super class constructor
执行期间会调用此块。
因此,可以在此块中进行初始化。
您可以initialize
个实例变量以及声明,一行或non-static block
内部。
然后,只要调用initialization
,就会发生此constructor
。
(因为它跟在块中执行代码之后)。
因此,该块实际上是constructor
执行的一部分。
另一方面,如果你在类本身中编写初始化代码,它没有任何意义,因为没有方法执行该行,因此是不正确的。
所以,方法1:与声明一起初始化:
class Foo {
Object x;
String s = (String) x;
}
或者,方法2:在声明后的块中初始化:
class Foo {
Object x;
String s;
{
s = (String) x;
}
}
请记住,在调用超类构造函数之后,在构造函数执行期间调用此非静态块。
答案 2 :(得分:2)
通常,类声明只能包含类主体声明。这些是:
该行
s = (String) x;
不是那些。
您可以使用@TheLostMind建议的初始化程序声明,或者按照@Turing85的建议将赋值放入构造函数中。您也可以将这样的一行放入其他方法中。你甚至可以做这样荒谬的事情:
class Foo {
Object x;
String s;
String s2 = s = (String) x;
}
声明x,s和s2的行都是字段声明。在s2行上第一个“=”之后的奇怪的东西是s2的所有初始化器。赋值表达式s = (String) x
是一个返回String的合法表达式,因此适合那里。
但是一个简单的s = (String) x;
是一个语句,而不是一个类主体声明,所以它根本不能按照Java规则(a.k.a.Java语言规范)去那里。