我想了解各种情况下类实例的初始化。
在JLS-7节12.5中,没有提到最终实例变量是如何以及何时初始化的?在实例变量被声明为最终的情况下,我能参考一点来理解这种行为吗?
public class Test {
public static void main(String args[]){
Child c1 = new Child();
}
}
class Parent{
final int a =30;
Parent(){
System.out.println("From super Contsrutor "+a);
meth();
}
void meth(){
System.out.println("From super");
}
}
class Child extends Parent{
final int e=super.a;
int b=30;
void meth(){
System.out.println("From Sub e=" +e+", b="+b);
}
}提供的输出如下
From super Contsrutor 30
From Sub e=0,b=0何地as
public class Test {
public static void main(String args[]){
Child c1 = new Child();
}
}
class Parent{
final int a =30;
Parent(){
System.out.println("From super Contsrutor "+a);
meth();
}
void meth(){
System.out.println("From super");
}
}
class Child extends Parent{
final int e=a;
void meth(){
System.out.println("From Sub " +e);
}
}给出的输出
From super Contsrutor 30
From Sub 30发布于 2014-05-14 18:15:12
这
final int e = a;是常量变量,常量表达式。在调用中
System.out.println("From Sub e=" +e+", b="+b);编译器可以用e的值30代替它的使用。
在……里面
final int e = super.a;变量e不是常量变量,因为super.a不是简单名称,因此值不能也不会被替换。
发布于 2014-05-14 18:17:37
第一段代码给出了如下输出
From super Contsrutor 30
From Sub e=0,b=0这是因为下面的原因。
首先,当我们执行new Child()时,子类的构造器开始执行
但是它的第一个语句在默认情况下是超级的,所以它会调用父类constrctor。
现在父类构造器有以下代码
{System.out.println(“来自超级Contsrutor "+a);meth();}
在这里,父类调用meth()方法,它的调用者实际上是子类的子对象,因此它调用子类meth()方法。
现在,当它从超级构造器调用子类meth()方法时,实际上还没有创建子对象,因此它的变量还没有初始化,但是我们同时打印了a和b的值。
因此,在子构造器执行完成之后,b在被分配之前得到0。
因此,像下面这样修改您的第一段代码将提供所需的输出,即将meth()调用放在子解析器中,而不是在父解析器上。
package com.kb.finalVariables;
public class Test {
public static void main(String args[]){
Child c1 = new Child();
}
}
class Parent{
final int a =30;
Parent(){
System.out.println("From super Contsrutor "+a);
// meth();
}
void meth(){
System.out.println("From super");
}
}
class Child extends Parent{
final int e=super.a;
int b=30;
public Child() {
meth();
}
void meth(){
System.out.println("From Sub e=" +e+", b="+b);
}
}发布于 2014-05-14 18:39:09
让我们找出程序的流程,我已经为它编写了下面的代码:
package com.test;
public class Test {
public static void main(String args[]) {
Child c1 = new Child();
}
}
class Parent {
final int a = 30;
static int count = 0;
{
System.out.println("Parent initialization block " + ++count);
}
Parent() {
System.out.println("Parent constructor " + ++count);
// System.out.println("From super Contsrutor " + a);
meth();
}
void meth() {
// System.out.println("From super");
System.out.println("Parent meth method " + ++count);
}
}
class Child extends Parent {
final int e = super.a;
int b = 30;
{
System.out.println("Child initialization block " + ++count);
}
public Child() {
System.out.println("Child constructor " + ++count);
}
void meth() {
System.out.println("Child meth method " + ++count);
// System.out.println("From Sub e=" + e + ", b=" + b);
}
}输出:
Parent initialization block 1
Parent constructor 2
Child meth method 3
Child initialization block 4
Child constructor 5首先,请记住,我已经为和Child类编写了Parent初始化块,这是在构造函数之前调用的。
现在,如果从创建meth对象的输出中可以看到,首先将Parent类加载到内存中,则调用Parent构造函数中的meth方法,该方法将调用 Child 类的 Child 方法E 223但Child但E 125Child>此时初始化块和E 226 Child E 130的构造函数不称为E 231,这意味着此时b不是初始化为30,而是初始化到d32默认值代码>d33,与d34/>变量相同。
https://stackoverflow.com/questions/23661541
复制相似问题