我有两个类,Parent和Child,代码如下:
public class Parent {
public String word;
}
父类只包含一个公共字段。
public class Child extends Parent {
//super.word = "Simple field assignment.";
{
System.out.println(word);
}
String word2 = super.word = "Field assignment.";
{
System.out.println(word);
super.word = "Initialization block.";
System.out.println(word);
}
public Child(){
super.word="Constructor.";
System.out.println(word);
}
}
我想问的问题是为什么不允许使用简单的赋值'super.word =“word”',但是下面的双重赋值是正常的。有人可以指出后者究竟发生了什么吗?
为什么在初始化块内允许赋值?
如果我运行以下主程序:
public class FieldTest {
public static void main (String[] args)
{
Child c = new Child();
System.out.println("1: "+c.word);
System.out.println("2: "+c.word2);
}
}
结果是:
null
Field assignment.
Initialization block.
Constructor.
1: Constructor.
2: Field assignment.
答案 0 :(得分:2)
声明
super.word = "Simple field assignment.";
在构造函数之外,初始化程序或方法不是有效的Java语法。您可以在声明字段时初始化字段
public class Parent {
public String word = "Don't use mutable public fields!"
}
并在子类的构造函数或初始值设定项中修改它们
public class Child extends Parent {
public Child() {
super();
this.word = "Don't mutate parent state like this...";
}
}
super关键字与字段组合仅在隐藏超类的变量时才有用:
public class Child extends Parent {
public String word = "Only for demonstration purposes - do not hide fields!";
public Child() {
super.word = "Mutating the hidden field.";
}
}
正如你从代码中看到的那样,这不应该是最终生产的东西 - 我不记得在我的职业生涯中曾经使用super.someField
。如果您不确定某些结构,请使用CheckStyle和FindBugs。如果您需要有关解决具体继承问题的任何提示,请告诉我。
答案 1 :(得分:0)
如果您指的是注释掉的行
super.word = "Simple field assignment.";
该行出错,因为它是语句直接在类体内发生“裸”。在那个位置只允许声明。实例初始化程序就是这样一个例子。
在另一点上,您对super
的使用完全是多余的。您可以删除它而不会影响语义,或者您可以使用this
代替相同的结果。
答案 2 :(得分:0)
尝试将child的定义更改为以下
public class Child extends Parent {
{
super.word = "Simple field assignment.";
System.out.println(word);
}
String word2 = super.word = "Field assignment.";
{
System.out.println(word);
super.word = "Initialization block.";
System.out.println(word);
}
public Child(){
super.word="Constructor.";
System.out.println(word);
}
}
即。在块内放置super.word =“简单字段赋值” - 所有非声明的代码都必须进入初始化块。请参阅here。
答案 3 :(得分:0)
不允许第一个赋值,因为它直接在类的内部,而另一个在一个块内,所以没关系。
要回答第二个问题,让我们看看发生了什么:
Child
正在实例化,因此第一个块被执行,打印word
,尚未初始化,因此它是null
。word2
的值为word
,其值为Field assignment.
,它们都包含此字符串。word
已打印:Field assignment.
word
的值为Initialization block.
word
已打印:Initialization block.
Child
的构造函数被调用,word
被赋予值Constructor.
并正在打印。word
的值:Constructor.
word2
的值:Field assignment.
答案 4 :(得分:0)
class Check {
//static block
static {
System.out.println("hello from Static");
}
//object block
{
System.out.println("This is my object block");
}
public static void main(String args[]) {
System.out.println("hello from main");
Check obj = new check();
}
}
这是输出:
hello from Static
hello from main
This is my object block
只要将类加载到JVM中,就会执行静态块。而在创建所述对象的实例时,将运行对象块或构造函数块。
欲了解更多信息,请访问
http://www.jusfortechies.com/java/core-java/static-blocks.php http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html