`

面试题--类成员变量的初始化时间

 
阅读更多
class B {
	B() {
		System.out.println("B");
		go();
	}
	private int a=1;
	public void go(){
		System.out.println("a="+a);
	}
}

public class A1 extends B {
	A1() {
		System.out.println("A1");
	}
	private int a=11;
	public void go(){
		System.out.println("a="+a);
	}
	public static void main(String[] args) {
		new A1();
	}
}

以上代码输出结果为: 
B
a=0
A1

 

我当时以为是输出a=11,结果回来跑了一把代码后,发现为0,即:先执行A1这时只是申明变量,并没赋值,然后执行B(),这时获取到a是A1里的,但还是初始值0呢,所以输出0.

后来经资料官方的解释为:对类变量的初始化是在执行完其构造方法的第一行代码(即this或super)后才开始的。

 

以下代码可以证实:

class B {
	B() {
		final B b=this;
		go();
		new Thread() {
			public void run() {
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				b.go();
			}
		}.start();
	}
	public void go(){
	}
}

public class A1 extends B {
	A1() {
		System.out.println("aa");
		go();
	}
	private int a=11;
	public void go(){
		System.out.println("a="+a);
	}
	public static void main(String[] args) {
		new A1();
	}
}

输出结果为:

a=0
aa
a=11//这个是23行输出的
a=11//这个是12行输出的,由于另起了线程,所以在输出的时候已经执行完了构造方法

1
5
分享到:
评论
4 楼 cwj158 2011-09-13  
super
Rainbow702 写道
引用
后来经资料官方的解释为:对类变量的初始化是在执行完其构造方法的第一行代码(即this或super)后才开始的。

这句话是OK的,你可以在 B 类的构造函数中的第一行加个
super();

然后 DEBUG 一下就知道了。
其他的你应该这么理解:
在新建一个A1实例时,B类的构造函数要先被调用,在B类的构造函数中有一句是调用了  go()  方法的,由于 A1 类中重写了这个方法,所以会来调用 A1 中的这个方法,但此时,A1 中的 a 变量还没有被初始化,所以打印出来的是 0.

嗯,好办法哈。
3 楼 Rainbow702 2011-09-11  
引用
后来经资料官方的解释为:对类变量的初始化是在执行完其构造方法的第一行代码(即this或super)后才开始的。

这句话是OK的,你可以在 B 类的构造函数中的第一行加个
super();

然后 DEBUG 一下就知道了。
其他的你应该这么理解:
在新建一个A1实例时,B类的构造函数要先被调用,在B类的构造函数中有一句是调用了  go()  方法的,由于 A1 类中重写了这个方法,所以会来调用 A1 中的这个方法,但此时,A1 中的 a 变量还没有被初始化,所以打印出来的是 0.
2 楼 cwj158 2011-09-11  
瘋叻ハ.兩 写道
第二个程序中final B b = this; 你想表达什么吗?

首先谢谢你关注我的代码哈,
主要是我想在第12行调用b.go(); 但由于内部类不能访问外部类方法中的局部变量,除非变量是final的(一般发生在方法中定义的内部类)。所以只能加个FINAL。
1 楼 瘋叻ハ.兩 2011-09-11  
第二个程序中final B b = this; 你想表达什么吗?

相关推荐

    java面试题-类的初始化顺序.doc

    这个顺序表明,无论类之间的继承关系如何,初始化顺序始终是:静态变量和静态初始化块先于非静态成员。在创建对象时,父类的初始化先于子类。这是Java语言规范所规定的,确保在子类访问父类的静态或非静态成员时,...

    3.ES6面试真题-84页.pdf

    - 使用 `const` 声明的变量必须在声明时进行初始化。 示例代码: ```javascript const a; // 报错:SyntaxError: Missing initializer in const declaration ``` #### 3. `var`、`let` 与 `const` 的对比 - ...

    JAVA面试题解惑系列——类的初始化顺序

    首先,需要了解Java类初始化的基本规则,即在类的静态变量、静态初始化块、变量、初始化块、构造器这五个部分中,它们的初始化顺序依次是:静态变量、静态初始化块、变量、初始化块、构造器。这个顺序在单个类中是...

    JSP面试题--基础

    ### JSP面试题详解 #### 1. HTTP 协议的无状态特性及有状态协议的概念 HTTP(HyperText Transfer Protocol)是一种应用层协议,用于从Web服务器传输超文本到本地浏览器的传输协议。它是一种**无状态协议**,这意味...

    JAVA面试题解惑系列类的初始化顺序JAVA程序员JAVA工程师面试必看.pdf

    3. **父类的非静态部分**:在创建子类实例时,首先执行父类的非静态变量初始化和非静态初始化块,然后调用父类的构造器。 4. **子类的非静态部分**:最后执行子类的非静态变量初始化和非静态初始化块,以及子类的...

    java私塾面试题----JAVA基础1.rar

    - 变量声明与初始化:理解不同类型的变量声明方式及其生命周期。 3. **运算符与表达式**: - 熟悉算术、比较、逻辑、位、赋值等各类运算符的使用。 - 了解短路逻辑运算符(&&, ||)与非短路逻辑运算符的区别。 ...

    java面试题-外企软件工程师面试题大全

    - 数组的操作,包括声明、初始化、遍历以及数组与集合的转换。 3. **集合框架**: - List、Set、Queue和Map接口的理解,以及ArrayList、LinkedList、HashSet、HashMap等实现类的特性。 - 集合操作,如迭代、查找...

    JAVA面试题解惑系列(一)——类的初始化顺序-JAVA程序员JAVA工程师面试必看.pdf

    2. **实例变量和初始化块**:当创建子类对象时,先执行父类的实例变量初始化和初始化块,接着执行子类的实例变量初始化和初始化块。这是因为在创建子类对象时,首先会创建父类的部分,然后再创建子类的部分。 3. **...

    JAVA面试题-基础部分3

    - **对象创建与内存分配**:了解对象在堆中如何分配和初始化。 - **垃圾收集**:理解GC的工作原理,包括可达性分析算法、垃圾收集器(如Serial、Parallel、CMS、G1等)以及内存调优。 5. **集合框架** - **List...

    java程序员经典笔试面试题汇总

    ### Java程序员经典笔试面试题汇总知识点解析 #### 一、程序执行顺序与静态变量初始化 **题目背景**:本题目旨在考察Java程序中类的加载过程以及不同成员(如静态变量、非静态变量等)的初始化顺序。 **题目示例*...

    iOS面试题-C部分

    ### iOS面试题-C部分知识点详解 #### 一、Static关键字的作用 1. **隐藏功能**:当我们在编译多个文件时,所有未加`static`前缀的全局变量和函数都具有全局可见性。添加`static`关键字后,变量或函数的作用域仅限于...

    iOS面试题-OC部分

    - 初始化时不会触发。 - 滚动UIScrollView时会触发。 - 旋转屏幕时会触发。 - 改变视图的`frame`属性时会触发。 - 改变UIView的大小时会触发。 #### 10. public、private、protected的区别 - **public:**公开访问...

    java面试题---传智博客和其他

    了解如何创建类,如何通过构造器初始化对象,以及抽象类、接口的区别和应用。 3. **集合框架**:ArrayList、LinkedList、HashSet、HashMap等是面试中的常见问题。理解它们的底层实现原理,如数组、链表、哈希表,...

    1.JavaScript面试真题-210页.zip

    - Vue CLI(项目初始化、脚手架工具) 5. **前端面试常见问题** - 性能优化(懒加载、资源预加载、首屏优化) - 错误处理与调试(try-catch、console工具、Source Map) - 浏览器兼容性问题(polyfill、Babel...

    深圳融天面试题--java

    考察变量的声明、初始化和作用域。 - **运算符与表达式**:掌握算术、比较、逻辑、位和赋值等运算符,理解运算符的优先级和结合性。 - **流程控制**:包括条件语句(if-else、switch-case)和循环语句(for、while...

    2024年java面试题-jvm性能调优面试题第二部分

    1. **堆区(Heap)**:堆区是用于存储初始化的对象、成员变量等数据的地方。所有对象实例和数组都需要在堆上分配空间。 - **新生代(Young Generation)**:由Eden区和Survivor区组成。 - **Eden区**:大部分新创建的...

    JAVA面试题解惑系列(一)——类的初始化顺序-JAVA程序员JAVA工程师面试必看.pdf,这是一份不错的文件

    JAVA面试题解惑系列(一)——类的初始化顺序 JAVA 是一门面向对象的编程语言,类的初始化顺序是 JAVA 程序员和 JAVA 工程师面试中一个非常重要的知识点。本文将详细讲解类的初始化顺序,并提供了相关的测试代码,...

    面试题-c++面试题一

    【C++面试题解析】 1. **变量的声明与定义的区别** 在C++中,变量的声明(declaration)是用来告诉编译器变量的名字和类型,但并不分配内存空间。而变量的定义(definition)是实际分配内存并初始化变量的时刻。一...

Global site tag (gtag.js) - Google Analytics