[英]Initialization of “final” instance variables
I would like to understand initialization of class instances in various cases.. 我想了解各种情况下类实例的初始化。
In JLS-7 Section 12.5, there was no mention of how and when final instance variables were initialized? 在JLS-7第12.5节中,没有提到最终实例变量的初始化方式和时间? Can some one point me reference to understand the behaviour in case of instance variables declared as final?
有人可以指出在实例变量被声明为final的情况下理解行为吗?
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);
}
}
is giving Output as following 输出如下
From super Contsrutor 30
From Sub e=0,b=0
Where 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);
}
}
is giving Output as 将输出作为
From super Contsrutor 30
From Sub 30
This 这个
final int e = a;
is a constant variable , a constant expression . 是一个常量变量 ,一个常量表达式 。 In the invocation
在调用中
System.out.println("From Sub e=" +e+", b="+b);
the compiler can replace the use of e
with its value, 30
. 编译器可以用其值
30
替换e
的使用。
In 在
final int e = super.a;
the variable e
is not a constant variable, because super.a
is not a simple name , and therefore the value cannot and will not be replaced. 变量
e
不是常量变量,因为super.a
不是简单的名称 ,因此该值不能也不会被替换。
first piece of Code is giving the output as below 第一段代码输出如下
From super Contsrutor 30
From Sub e=0,b=0
This is because of below reason. 这是因为以下原因。
first thing when we do new Child()
, the constrcutor of Child class starts execution 当我们做
new Child()
,Child类的构造者开始执行
but its first statement is super by default so it gives a call to parent class constrctor 但它的第一个语句默认为super,因此它会调用父类constrctor
now Parent class constrcutor has below code 现在父类constrcutor有下面的代码
Parent(){ System.out.println("From super Contsrutor "+a); Parent(){System.out.println(“来自超级Contsrutor”+ a); meth();
甲基(); }
}
so here parent class is calling meth() method and its caller is actually a subclass child's object so it calls child class meth() method. 所以这里的父类调用了meth()方法,它的调用者实际上是子类的子对象,因此它调用了子类的meth()方法。
now when it calls child class meth() method from super constrcutor actually child object is not yet created so its variables are not yet initialized but we are printing the values for both a and b. 现在当它从super constrcutor调用child class meth()方法时,实际上还没有创建子对象,所以它的变量尚未初始化,但我们正在打印a和b的值。
so b gets 0 before getting assigned after child constrcutor gets execution completed. 因此,在孩子建筑师完成执行后,b在获得分配之前得到0。
so changing your first piece of code like below will give desired output ie putting meth() call inside child constrctor rather than on parent constrcutor. 所以改变你的第一段代码就像下面那样会产生所需的输出,即将meth()调用放在子构造函数中,而不是父母constrcutor。
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);
}
}
Lets find out the flow of the program, I have written below code for it: 让我们找出程序的流程,我在下面写了代码:
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);
}
}
Output: 输出:
Parent initialization block 1
Parent constructor 2
Child meth method 3
Child initialization block 4
Child constructor 5
First of all remember I have written initialization block for Parent
and Child
class, which is called before constructor. 首先要记住我已经为
Parent
和Child
类编写了初始化块 ,它在构造函数之前调用。
Now if you can see from output on creation of Child
object first Parent
class is loaded into memory, then you have called meth
method inside Parent
constructor that will call meth
method of Child
class but Child
but at this time initialization block and constructor of Child
is not called that means at this time b is not initialized to 30 but to int
default value 0
, same case with e
variable. 现在,如果你可以从创造的输出看
Child
对象第一Parent
类被加载到内存中,那么你就称为meth
内部方法Parent
构造函数,将调用meth
的方法, Child
类 ,但Child
却在这个时候初始化块和构造Child
是没有调用 ,这意味着此时b未初始化为30但是对于int
默认值0
,与e
变量的情况相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.