Java容易搞错的知识点-觉得基础扎实的来看
以下几个知识点是非常容易搞混的Java知识点。大家不准开编译器,并且先不看答案,要是能全部答对,那Java基础是挺牢固的。如果答对了,还能分析出具体原因,那算你NB。近段时间有参加一些公司的面试,做了一些基础题,发现总有掌握得不好的地方。今天一并总结了这些问题,希望对大家有所帮助。如果大家认为还有其它易混淆的地方,也可以跟贴发出来,大家一起讨论。从大家的回贴中,发现了不少自已不知道的东西,想看的就看吧。
一、关于Switch
代码:
结果:
x+y equals z:true
a == z:false
x == hello:true
a == helloworld:true
a == x+y:false
分析:
1.String.equals()方法比较的是字符串的内容,所以(x + y).equals(z)为true.
2.“==”比较的是 String 实例的引用,很明显 a 和z 并不是同一个 String 实例,所以(a == z)为false.
3.根据常量池的知识,容易得知(x == "hello")和(a == "hello" + "world")都为true.
(常量池指的是在编译期被确定并被保存在已编译的.class 文件中的一些数据。它包含了
关于方法、类、接口等,当然还有字符串常量的信息。也就是所谓的持久代。)
4.那么(a == (x + y))为什么是false呢?这点暂点有点不大清楚。初步认为是x+y是引用相加,不能放入常量池。
三、Override覆盖
代码:
结果:
The value of c :0
分析:
public void Constructor()并不是一个真正的构造函数,而是一个方法。所以c的值为默认值0.
六、提前引用
代码:
结果:
first = 0
分析:
由于在初始化second之前test方法就访问了它,那么方法得到的是second的默认值,即 0。 因此输出结果first= 0,而不是2。假如你使用方法调用来初始化静态变量,那么你必须保证 这些方法并不依赖于在它们之后声明的其它静态变量。静态变量以及静态初始化块是在类被加载进 JVM 时执行初始化操作的。Java 语言规范8.5节指出“静态初始化块和静态变量是按照其在代码中出现的顺序依次执行初始化操作的,而不能在类变量声明出现之前就引用它”。
七、对象引用
代码:
结果:
ab,b
ab,ab
分析:
大家来分析一下这题,我还没有完全理解。
我的分析,可能是错的,哈哈,算是抛砖引玉。
1.a.append(b);-->ab 。因为a是引用,所以调用a的方法,相当于直接调用jvm中的a,所做的append也相当于直接在对象上操作,生效。
2.append方法中第一次b=a,-->b。因为a,b都为main方法内局部变量,跨append方法作用域b对a的引用不生效。
3.main方法中第二次b=a,-->ab。因为在同一作用域方法中,b对a的引用生效,。
结果:
x+y equals z:true
a == z:false
x == hello:true
a == helloworld:true
a == x+y:false
分析:
1.String.equals()方法比较的是字符串的内容,所以(x + y).equals(z)为true.
2.“==”比较的是 String 实例的引用,很明显 a 和z 并不是同一个 String 实例,所以(a == z)为false.
3.根据常量池的知识,容易得知(x == "hello")和(a == "hello" + "world")都为true.
(常量池指的是在编译期被确定并被保存在已编译的.class 文件中的一些数据。它包含了
关于方法、类、接口等,当然还有字符串常量的信息。也就是所谓的持久代。)
4.那么(a == (x + y))为什么是false呢?这点暂点有点不大清楚。初步认为是x+y是引用相加,不能放入常量池。
三、Override覆盖
代码:
结果:
The value of c :0
分析:
public void Constructor()并不是一个真正的构造函数,而是一个方法。所以c的值为默认值0.
六、提前引用
代码:
结果:
first = 0
分析:
由于在初始化second之前test方法就访问了它,那么方法得到的是second的默认值,即 0。 因此输出结果first= 0,而不是2。假如你使用方法调用来初始化静态变量,那么你必须保证 这些方法并不依赖于在它们之后声明的其它静态变量。静态变量以及静态初始化块是在类被加载进 JVM 时执行初始化操作的。Java 语言规范8.5节指出“静态初始化块和静态变量是按照其在代码中出现的顺序依次执行初始化操作的,而不能在类变量声明出现之前就引用它”。
七、对象引用
代码:
结果:
ab,b
ab,ab
分析:
大家来分析一下这题,我还没有完全理解。
我的分析,可能是错的,哈哈,算是抛砖引玉。
1.a.append(b);-->ab 。因为a是引用,所以调用a的方法,相当于直接调用jvm中的a,所做的append也相当于直接在对象上操作,生效。
2.append方法中第一次b=a,-->b。因为a,b都为main方法内局部变量,跨append方法作用域b对a的引用不生效。
3.main方法中第二次b=a,-->ab。因为在同一作用域方法中,b对a的引用生效,。
因为x,y都是引用数据类型,都可以看成是一个对象,这样两个应用数据类型相加,会在堆中产生一个新的对象,所以就不相等了
结果:
x+y equals z:true
a == z:false
x == hello:true
a == helloworld:true
a == x+y:false
分析:
1.String.equals()方法比较的是字符串的内容,所以(x + y).equals(z)为true.
2.“==”比较的是 String 实例的引用,很明显 a 和z 并不是同一个 String 实例,所以(a == z)为false.
3.根据常量池的知识,容易得知(x == "hello")和(a == "hello" + "world")都为true.
(常量池指的是在编译期被确定并被保存在已编译的.class 文件中的一些数据。它包含了
关于方法、类、接口等,当然还有字符串常量的信息。也就是所谓的持久代。)
4.那么(a == (x + y))为什么是false呢?这点暂点有点不大清楚。初步认为是x+y是引用相加,不能放入常量池。
三、Override覆盖
代码:
结果:
The value of c :0
分析:
public void Constructor()并不是一个真正的构造函数,而是一个方法。所以c的值为默认值0.
六、提前引用
代码:
结果:
first = 0
分析:
由于在初始化second之前test方法就访问了它,那么方法得到的是second的默认值,即 0。 因此输出结果first= 0,而不是2。假如你使用方法调用来初始化静态变量,那么你必须保证 这些方法并不依赖于在它们之后声明的其它静态变量。静态变量以及静态初始化块是在类被加载进 JVM 时执行初始化操作的。Java 语言规范8.5节指出“静态初始化块和静态变量是按照其在代码中出现的顺序依次执行初始化操作的,而不能在类变量声明出现之前就引用它”。
七、对象引用
代码:
结果:
ab,b
ab,ab
分析:
大家来分析一下这题,我还没有完全理解。
我的分析,可能是错的,哈哈,算是抛砖引玉。
1.a.append(b);-->ab 。因为a是引用,所以调用a的方法,相当于直接调用jvm中的a,所做的append也相当于直接在对象上操作,生效。
2.append方法中第一次b=a,-->b。因为a,b都为main方法内局部变量,跨append方法作用域b对a的引用不生效。
3.main方法中第二次b=a,-->ab。因为在同一作用域方法中,b对a的引用生效,。
就是true了,因为这时候是常量,编译期间就能确定的值,就直接饮用字符串池里的。
100 楼 h521999 2011-03-18 曾经记得藏圩人整理过类似的一系列题目。 101 楼 Jathon_hs 2011-03-18 还行,除了a==(x+y)没答对 102 楼 wdz567 2011-03-19 最后一条应该问题应该是在a.append(b) 上这个地方被append搞了个值传递
而b没有。如果b使用b.append(a) 我想也应该可以修改 103 楼 nightbin0420 2011-03-29 学习了,还是有些没明白..看来得加强基础了! 104 楼 zhangwe415 2011-03-29 看的晕晕的,终于搞懂了 105 楼 biqiang86 2011-04-10 sdtm1016 写道SCJP 不少这样的题 ,如果不是靠背过关,而是扎实分析,还是挺有用的
对对,这些东西建议去看看scjp的考试资料,都是这些问题... 106 楼 greatrobert 2011-04-12 akunamotata 写道关于第二题,我画了个图,有错请务必指出,免得误人子弟。
显然错了,x、y也在常量池里面