为什么我不能在下一行分配?

时间:2015-07-19 17:34:09

标签: java string object

为什么以下编译

class Foo {
    Object x;
    String s = (String) x;
}

以下不编译?

class Foo {
    Object x;
    String s;
    s = (String) x;
}

我错过了一些JLS规则吗?我知道这一定是愚蠢的,但我仍然需要知道背后的原因。

3 个答案:

答案 0 :(得分:2)

您可以使用实例级别块

{
    s = (String) x;
}

赋值语句如果不属于声明语句,则应属于某个块。  可以是任何东西(方法,构造函数等)

答案 1 :(得分:2)

non-static块(此处标记为{ })可以访问variablesmethods。在调用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语言规范)去那里。