- 浏览: 27980 次
- 性别:
- 来自: 北京
最新评论
-
shenad8927:
你说要是a是白的 bc都是黑的a是不就跪了。。我看a主要还是拼 ...
国王3个囚犯戴帽子,帽子不是黑色就是白色---逻辑题。 -
hekuilove:
nophaern 写道如果-允许囚犯单独呆着,但是要考虑船上和 ...
囚犯过河问题-逻辑题 -
hekuilove:
一囚一守过河 一囚回二囚过河一囚回一囚一守过河一囚回二囚过河一 ...
囚犯过河问题-逻辑题 -
smithfox:
show heap status 这个不错
Flex工程编译慢的优化方案 -
greatrobert:
<div class="quote_title ...
Java容易搞错的知识点-觉得基础扎实的来看
以下几个知识点是非常容易搞混的Java知识点。大家不准开编译器,并且先不看答案,要是能全部答对,那Java基础是挺牢固的。如果答对了,还能分析出具体原因,那算你NB。近段时间有参加一些公司的面试,做了一些基础题,发现总有掌握得不好的地方。今天一并总结了这些问题,希望对大家有所帮助。如果大家认为还有其它易混淆的地方,也可以跟贴发出来,大家一起讨论。从大家的回贴中,发现了不少自已不知道的东西,想看的就看吧。
一、关于Switch
代码:
结果:
2
3
4
分析:
少了break;所以2以下的case和default都执行了一遍。
二、Equals和==运算符
代码:
结果:
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覆盖
代码:
结果:
parent static say
child say
分析:
1.我们创建了一个Parent类的实例。变量 p 的数据类型为 Parent 类 但是它仍旧是 Child 类的一个实例。因为Child类覆盖了Parent类的方法say2(),所以p.say2()调用为子类的方法。
2.为什么p.say()却是调用父类Parent的方法呢?因为Java中规定“实例方法被覆盖,静态方法被隐藏”.
关于Override的一些规则:
用子类的静态方法隐藏父类中同样标识的实例方法是不合法的,编译器将会报错;
用子类的实例方法覆盖父类中同样标识的静态方法也是不合法的,编译器同样会报错;
带关键字 final的方法(静态和实例方法)都不能被覆盖;
实例方法能够被覆盖;
抽象方法必须在具体类中被覆盖。
四、Java强类型
代码:
结果:
7.0
分析:
Java 是强类型的 strongly type,它支持8 种基本数据类型。通过对这些基本数据类型用法的严格检查 Java 编译器能够及时地在开发过程中捕捉到许多简单细微的错误。基本数据类型的转换可以隐性地发生,所以转换时会有精度损失。由于1/4和3/4发生隐性类型转换,精度损失,不会生成0.25和0.75,所以有分号的数都为0。
五、假构造函数
代码:
结果:
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也在常量池里面
对对,这些东西建议去看看scjp的考试资料,都是这些问题...
此言与我心中所想完全一致
我奇怪的就是在
public static void append(Aa a1, Aa a2) {
a1.setA(a2.getA());
a2 = a1;
}
这当中a1 a2跟第七里面的StringBuffer难道不是一样的吗》?传递过来的都是对象的引用地址啊。既然StringBuffer在方法里面只是把局部变量b的指向修改了,而main没变,那我改的这个方法里面,有什么不同吗?
人家有两个字符串合并,你这就直接设置,我差点也给你蒙了,再仔细看一下代码
一、关于Switch
代码:
public class TestSwitch { public static void main(String[] args) { int i = 2; switch (i) { case 1: System.out.println(1); case 2: System.out.println(2); case 3: System.out.println(3); default: System.out.println(4); } } }
结果:
2
3
4
分析:
少了break;所以2以下的case和default都执行了一遍。
二、Equals和==运算符
代码:
public static void test() { String x = "hello"; String y = "world"; String z = new String("helloworld"); String a = "helloworld"; System.out.println("x+y equals z:" + (x + y).equals(z)); System.out.println("a == z:" + (a == z)); System.out.println("x == hello:" + (x == "hello")); System.out.println("a == helloworld:" + (a == "hello" + "world")); System.out.println("a == x+y:" + (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覆盖
代码:
public class Parent { public static String say() { return "parent static say"; } public String say2() { return "parent say"; } } public class Child extends Parent { public static String say() { return "child static say"; } public String say2() { return "child say"; } } /** * @author 子弹哥 * */ public class OverrideTest { public static void main(String[] args) { Parent p = new Child(); System.out.println(p.say()); System.out.println(p.say2()); } }
结果:
parent static say
child say
分析:
1.我们创建了一个Parent类的实例。变量 p 的数据类型为 Parent 类 但是它仍旧是 Child 类的一个实例。因为Child类覆盖了Parent类的方法say2(),所以p.say2()调用为子类的方法。
2.为什么p.say()却是调用父类Parent的方法呢?因为Java中规定“实例方法被覆盖,静态方法被隐藏”.
关于Override的一些规则:
用子类的静态方法隐藏父类中同样标识的实例方法是不合法的,编译器将会报错;
用子类的实例方法覆盖父类中同样标识的静态方法也是不合法的,编译器同样会报错;
带关键字 final的方法(静态和实例方法)都不能被覆盖;
实例方法能够被覆盖;
抽象方法必须在具体类中被覆盖。
四、Java强类型
代码:
/** * @author 子弹哥 * */ public class Type { public static void main(String[] args) { double i = 5.0; double j = 1 / 4 + 3 / 4 + i + 12 / 6.0 + 3 / 4 + 1 / 4; System.out.println(j); } }
结果:
7.0
分析:
Java 是强类型的 strongly type,它支持8 种基本数据类型。通过对这些基本数据类型用法的严格检查 Java 编译器能够及时地在开发过程中捕捉到许多简单细微的错误。基本数据类型的转换可以隐性地发生,所以转换时会有精度损失。由于1/4和3/4发生隐性类型转换,精度损失,不会生成0.25和0.75,所以有分号的数都为0。
五、假构造函数
代码:
/** * @author 子弹哥 * */ public class Constructor { private int a, b, c; public void Constructor() { a = 3; b = 5; c = a + b; } public void test() { System.out.println("The value of c :" + c); } public static void main(String[] args) { Constructor c = new Constructor(); c.test(); } }
结果:
The value of c :0
分析:
public void Constructor()并不是一个真正的构造函数,而是一个方法。所以c的值为默认值0.
六、提前引用
代码:
/** * @author 子弹哥 * */ public class ForwardReference { static int first = test(); static int second = 2; static int test() { return second; } public static void main(String[] args) { System.out.println("first = " + first); } }
结果:
first = 0
分析:
由于在初始化second之前test方法就访问了它,那么方法得到的是second的默认值,即 0。 因此输出结果first= 0,而不是2。假如你使用方法调用来初始化静态变量,那么你必须保证 这些方法并不依赖于在它们之后声明的其它静态变量。静态变量以及静态初始化块是在类被加载进 JVM 时执行初始化操作的。Java 语言规范8.5节指出“静态初始化块和静态变量是按照其在代码中出现的顺序依次执行初始化操作的,而不能在类变量声明出现之前就引用它”。
七、对象引用
代码:
/** * @author 子弹哥 * */ public class TestRef { public static void main(String[] args) { StringBuffer a = new StringBuffer("a"); StringBuffer b = new StringBuffer("b"); append(a, b); System.out.println(a.toString() + "," + b.toString()); b = a; System.out.println(a.toString() + "," + b.toString()); } public static void append(StringBuffer a, StringBuffer b) { a.append(b); b = a; } }
结果:
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的引用生效,。
评论
106 楼
greatrobert
2011-04-12
akunamotata 写道
关于第二题,我画了个图,有错请务必指出,免得误人子弟。
显然错了,x、y也在常量池里面
105 楼
biqiang86
2011-04-10
sdtm1016 写道
SCJP 不少这样的题 ,如果不是靠背过关,而是扎实分析,还是挺有用的
对对,这些东西建议去看看scjp的考试资料,都是这些问题...
104 楼
zhangwe415
2011-03-29
看的晕晕的,终于搞懂了
103 楼
nightbin0420
2011-03-29
学习了,还是有些没明白..看来得加强基础了!
102 楼
wdz567
2011-03-19
最后一条应该问题应该是在a.append(b) 上这个地方被append搞了个值传递
而b没有。如果b使用b.append(a) 我想也应该可以修改
而b没有。如果b使用b.append(a) 我想也应该可以修改
101 楼
Jathon_hs
2011-03-18
还行,除了a==(x+y)没答对
100 楼
h521999
2011-03-18
曾经记得藏圩人整理过类似的一系列题目。
99 楼
pjcai
2011-03-16
x跟y是final的下面
System.out.println("a == x+y:" + (a == (x + y)));
就是true了,因为这时候是常量,编译期间就能确定的值,就直接饮用字符串池里的。
System.out.println("a == x+y:" + (a == (x + y)));
就是true了,因为这时候是常量,编译期间就能确定的值,就直接饮用字符串池里的。
98 楼
sunlzx
2011-03-16
这帖子挺给力的
97 楼
hommy8
2011-03-09
fellatioyzx 写道
我都答对了
关于最后一题的话,由于java方法传值是值传递,所以方法里面的ab虽然和方法外的ab指向的对象一样,但是这两个引用在栈中的位置不一样。
过程大概是首先在栈中复制引用a为a',b为b',并令a'指向a所指的在堆中的StringBuffer对象,b'指向b所指的在堆中的StringBuffer对象。
因此方法中的b=a只是起到了b'=a'的作用,并没有影响方法外b的指向。
关于最后一题的话,由于java方法传值是值传递,所以方法里面的ab虽然和方法外的ab指向的对象一样,但是这两个引用在栈中的位置不一样。
过程大概是首先在栈中复制引用a为a',b为b',并令a'指向a所指的在堆中的StringBuffer对象,b'指向b所指的在堆中的StringBuffer对象。
因此方法中的b=a只是起到了b'=a'的作用,并没有影响方法外b的指向。
此言与我心中所想完全一致
96 楼
kingwolf543
2011-03-09
java解惑上说的很明白啊
95 楼
thihy
2011-03-09
那么(a == (x + y))为什么是false呢?这点暂点有点不大清楚。初步认为是x+y是引用相加,不能放入常量池。
因为你的x、y不是final的,无法在编译期间加入常量池。
因为你的x、y不是final的,无法在编译期间加入常量池。
94 楼
ljinkai
2011-03-09
这里有最后一题的详细说明:http://anna-zr.iteye.com/blog/382459
93 楼
99381837
2011-03-09
fastbo 写道
以下几个知识点是非常容易搞混的Java知识点。大家不准开编译器,并且先不看答案,要是能全部答对,那Java基础是挺牢固的。如果答对了,还能分析出具体原因,那算你NB。近段时间有参加一些公司的面试,做了一些基础题,发现总有掌握得不好的地方。今天一并总结了这些问题,希望对大家有所帮助。如果大家认为还有其它易混淆的地方,也可以跟贴发出来,大家一起讨论。从大家的回贴中,发现了不少自已不知道的东西,想看的就看吧。
一、关于Switch
代码:
结果:
2
3
4
分析:
少了break;所以2以下的case和default都执行了一遍。
二、Equals和==运算符
代码:
结果:
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覆盖
代码:
结果:
parent static say
child say
分析:
1.我们创建了一个Parent类的实例。变量 p 的数据类型为 Parent 类 但是它仍旧是 Child 类的一个实例。因为Child类覆盖了Parent类的方法say2(),所以p.say2()调用为子类的方法。
2.为什么p.say()却是调用父类Parent的方法呢?因为Java中规定“实例方法被覆盖,静态方法被隐藏”.
关于Override的一些规则:
用子类的静态方法隐藏父类中同样标识的实例方法是不合法的,编译器将会报错;
用子类的实例方法覆盖父类中同样标识的静态方法也是不合法的,编译器同样会报错;
带关键字 final的方法(静态和实例方法)都不能被覆盖;
实例方法能够被覆盖;
抽象方法必须在具体类中被覆盖。
四、Java强类型
代码:
结果:
7.0
分析:
Java 是强类型的 strongly type,它支持8 种基本数据类型。通过对这些基本数据类型用法的严格检查 Java 编译器能够及时地在开发过程中捕捉到许多简单细微的错误。基本数据类型的转换可以隐性地发生,所以转换时会有精度损失。由于1/4和3/4发生隐性类型转换,精度损失,不会生成0.25和0.75,所以有分号的数都为0。
五、假构造函数
代码:
结果:
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的引用生效,。
一、关于Switch
代码:
public class TestSwitch { public static void main(String[] args) { int i = 2; switch (i) { case 1: System.out.println(1); case 2: System.out.println(2); case 3: System.out.println(3); default: System.out.println(4); } } }
结果:
2
3
4
分析:
少了break;所以2以下的case和default都执行了一遍。
二、Equals和==运算符
代码:
public static void test() { String x = "hello"; String y = "world"; String z = new String("helloworld"); String a = "helloworld"; System.out.println("x+y equals z:" + (x + y).equals(z)); System.out.println("a == z:" + (a == z)); System.out.println("x == hello:" + (x == "hello")); System.out.println("a == helloworld:" + (a == "hello" + "world")); System.out.println("a == x+y:" + (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覆盖
代码:
public class Parent { public static String say() { return "parent static say"; } public String say2() { return "parent say"; } } public class Child extends Parent { public static String say() { return "child static say"; } public String say2() { return "child say"; } } /** * @author 子弹哥 * */ public class OverrideTest { public static void main(String[] args) { Parent p = new Child(); System.out.println(p.say()); System.out.println(p.say2()); } }
结果:
parent static say
child say
分析:
1.我们创建了一个Parent类的实例。变量 p 的数据类型为 Parent 类 但是它仍旧是 Child 类的一个实例。因为Child类覆盖了Parent类的方法say2(),所以p.say2()调用为子类的方法。
2.为什么p.say()却是调用父类Parent的方法呢?因为Java中规定“实例方法被覆盖,静态方法被隐藏”.
关于Override的一些规则:
用子类的静态方法隐藏父类中同样标识的实例方法是不合法的,编译器将会报错;
用子类的实例方法覆盖父类中同样标识的静态方法也是不合法的,编译器同样会报错;
带关键字 final的方法(静态和实例方法)都不能被覆盖;
实例方法能够被覆盖;
抽象方法必须在具体类中被覆盖。
四、Java强类型
代码:
/** * @author 子弹哥 * */ public class Type { public static void main(String[] args) { double i = 5.0; double j = 1 / 4 + 3 / 4 + i + 12 / 6.0 + 3 / 4 + 1 / 4; System.out.println(j); } }
结果:
7.0
分析:
Java 是强类型的 strongly type,它支持8 种基本数据类型。通过对这些基本数据类型用法的严格检查 Java 编译器能够及时地在开发过程中捕捉到许多简单细微的错误。基本数据类型的转换可以隐性地发生,所以转换时会有精度损失。由于1/4和3/4发生隐性类型转换,精度损失,不会生成0.25和0.75,所以有分号的数都为0。
五、假构造函数
代码:
/** * @author 子弹哥 * */ public class Constructor { private int a, b, c; public void Constructor() { a = 3; b = 5; c = a + b; } public void test() { System.out.println("The value of c :" + c); } public static void main(String[] args) { Constructor c = new Constructor(); c.test(); } }
结果:
The value of c :0
分析:
public void Constructor()并不是一个真正的构造函数,而是一个方法。所以c的值为默认值0.
六、提前引用
代码:
/** * @author 子弹哥 * */ public class ForwardReference { static int first = test(); static int second = 2; static int test() { return second; } public static void main(String[] args) { System.out.println("first = " + first); } }
结果:
first = 0
分析:
由于在初始化second之前test方法就访问了它,那么方法得到的是second的默认值,即 0。 因此输出结果first= 0,而不是2。假如你使用方法调用来初始化静态变量,那么你必须保证 这些方法并不依赖于在它们之后声明的其它静态变量。静态变量以及静态初始化块是在类被加载进 JVM 时执行初始化操作的。Java 语言规范8.5节指出“静态初始化块和静态变量是按照其在代码中出现的顺序依次执行初始化操作的,而不能在类变量声明出现之前就引用它”。
七、对象引用
代码:
/** * @author 子弹哥 * */ public class TestRef { public static void main(String[] args) { StringBuffer a = new StringBuffer("a"); StringBuffer b = new StringBuffer("b"); append(a, b); System.out.println(a.toString() + "," + b.toString()); b = a; System.out.println(a.toString() + "," + b.toString()); } public static void append(StringBuffer a, StringBuffer b) { a.append(b); b = a; } }
结果:
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的引用生效,。
92 楼
oryjk
2011-03-08
String x = "hello";
String y = "world";
String a = "helloworld";
System.out.println("a == x+y:" + (a == (x + y)));
因为x,y都是引用数据类型,都可以看成是一个对象,这样两个应用数据类型相加,会在堆中产生一个新的对象,所以就不相等了
String y = "world";
String a = "helloworld";
System.out.println("a == x+y:" + (a == (x + y)));
因为x,y都是引用数据类型,都可以看成是一个对象,这样两个应用数据类型相加,会在堆中产生一个新的对象,所以就不相等了
91 楼
beneo
2011-03-08
第七题弄明白的条件是,你么知道,传递的只是引用的拷贝
90 楼
云和山的彼端
2011-03-08
这更应该叫面试知识点,或者说三年以下程序员面试知识点。
89 楼
ayumi11111
2011-03-08
fastbo 写道
以下几个知识点是非常容易搞混的Java知识点。大家不准开编译器,并且先不看答案,要是能全部答对,那Java基础是挺牢固的。如果答对了,还能分析出具体原因,那算你NB。近段时间有参加一些公司的面试,做了一些基础题,发现总有掌握得不好的地方。今天一并总结了这些问题,希望对大家有所帮助。如果大家认为还有其它易混淆的地方,也可以跟贴发出来,大家一起讨论。从大家的回贴中,发现了不少自已不知道的东西,想看的就看吧。
一、关于Switch
代码:
结果:
2
3
4
分析:
少了break;所以2以下的case和default都执行了一遍。
二、Equals和==运算符
代码:
结果:
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覆盖
代码:
结果:
parent static say
child say
分析:
1.我们创建了一个Parent类的实例。变量 p 的数据类型为 Parent 类 但是它仍旧是 Child 类的一个实例。因为Child类覆盖了Parent类的方法say2(),所以p.say2()调用为子类的方法。
2.为什么p.say()却是调用父类Parent的方法呢?因为Java中规定“实例方法被覆盖,静态方法被隐藏”.
关于Override的一些规则:
用子类的静态方法隐藏父类中同样标识的实例方法是不合法的,编译器将会报错;
用子类的实例方法覆盖父类中同样标识的静态方法也是不合法的,编译器同样会报错;
带关键字 final的方法(静态和实例方法)都不能被覆盖;
实例方法能够被覆盖;
抽象方法必须在具体类中被覆盖。
四、Java强类型
代码:
结果:
7.0
分析:
Java 是强类型的 strongly type,它支持8 种基本数据类型。通过对这些基本数据类型用法的严格检查 Java 编译器能够及时地在开发过程中捕捉到许多简单细微的错误。基本数据类型的转换可以隐性地发生,所以转换时会有精度损失。由于1/4和3/4发生隐性类型转换,精度损失,不会生成0.25和0.75,所以有分号的数都为0。
五、假构造函数
代码:
结果:
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的引用生效,。
一、关于Switch
代码:
public class TestSwitch { public static void main(String[] args) { int i = 2; switch (i) { case 1: System.out.println(1); case 2: System.out.println(2); case 3: System.out.println(3); default: System.out.println(4); } } }
结果:
2
3
4
分析:
少了break;所以2以下的case和default都执行了一遍。
二、Equals和==运算符
代码:
public static void test() { String x = "hello"; String y = "world"; String z = new String("helloworld"); String a = "helloworld"; System.out.println("x+y equals z:" + (x + y).equals(z)); System.out.println("a == z:" + (a == z)); System.out.println("x == hello:" + (x == "hello")); System.out.println("a == helloworld:" + (a == "hello" + "world")); System.out.println("a == x+y:" + (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覆盖
代码:
public class Parent { public static String say() { return "parent static say"; } public String say2() { return "parent say"; } } public class Child extends Parent { public static String say() { return "child static say"; } public String say2() { return "child say"; } } /** * @author 子弹哥 * */ public class OverrideTest { public static void main(String[] args) { Parent p = new Child(); System.out.println(p.say()); System.out.println(p.say2()); } }
结果:
parent static say
child say
分析:
1.我们创建了一个Parent类的实例。变量 p 的数据类型为 Parent 类 但是它仍旧是 Child 类的一个实例。因为Child类覆盖了Parent类的方法say2(),所以p.say2()调用为子类的方法。
2.为什么p.say()却是调用父类Parent的方法呢?因为Java中规定“实例方法被覆盖,静态方法被隐藏”.
关于Override的一些规则:
用子类的静态方法隐藏父类中同样标识的实例方法是不合法的,编译器将会报错;
用子类的实例方法覆盖父类中同样标识的静态方法也是不合法的,编译器同样会报错;
带关键字 final的方法(静态和实例方法)都不能被覆盖;
实例方法能够被覆盖;
抽象方法必须在具体类中被覆盖。
四、Java强类型
代码:
/** * @author 子弹哥 * */ public class Type { public static void main(String[] args) { double i = 5.0; double j = 1 / 4 + 3 / 4 + i + 12 / 6.0 + 3 / 4 + 1 / 4; System.out.println(j); } }
结果:
7.0
分析:
Java 是强类型的 strongly type,它支持8 种基本数据类型。通过对这些基本数据类型用法的严格检查 Java 编译器能够及时地在开发过程中捕捉到许多简单细微的错误。基本数据类型的转换可以隐性地发生,所以转换时会有精度损失。由于1/4和3/4发生隐性类型转换,精度损失,不会生成0.25和0.75,所以有分号的数都为0。
五、假构造函数
代码:
/** * @author 子弹哥 * */ public class Constructor { private int a, b, c; public void Constructor() { a = 3; b = 5; c = a + b; } public void test() { System.out.println("The value of c :" + c); } public static void main(String[] args) { Constructor c = new Constructor(); c.test(); } }
结果:
The value of c :0
分析:
public void Constructor()并不是一个真正的构造函数,而是一个方法。所以c的值为默认值0.
六、提前引用
代码:
/** * @author 子弹哥 * */ public class ForwardReference { static int first = test(); static int second = 2; static int test() { return second; } public static void main(String[] args) { System.out.println("first = " + first); } }
结果:
first = 0
分析:
由于在初始化second之前test方法就访问了它,那么方法得到的是second的默认值,即 0。 因此输出结果first= 0,而不是2。假如你使用方法调用来初始化静态变量,那么你必须保证 这些方法并不依赖于在它们之后声明的其它静态变量。静态变量以及静态初始化块是在类被加载进 JVM 时执行初始化操作的。Java 语言规范8.5节指出“静态初始化块和静态变量是按照其在代码中出现的顺序依次执行初始化操作的,而不能在类变量声明出现之前就引用它”。
七、对象引用
代码:
/** * @author 子弹哥 * */ public class TestRef { public static void main(String[] args) { StringBuffer a = new StringBuffer("a"); StringBuffer b = new StringBuffer("b"); append(a, b); System.out.println(a.toString() + "," + b.toString()); b = a; System.out.println(a.toString() + "," + b.toString()); } public static void append(StringBuffer a, StringBuffer b) { a.append(b); b = a; } }
结果:
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的引用生效,。
88 楼
broguy
2011-03-08
给力撒,拿来看看
87 楼
miaofm
2011-03-08
forsecond 写道
我奇怪的就是在
public static void append(Aa a1, Aa a2) {
a1.setA(a2.getA());
a2 = a1;
}
这当中a1 a2跟第七里面的StringBuffer难道不是一样的吗》?传递过来的都是对象的引用地址啊。既然StringBuffer在方法里面只是把局部变量b的指向修改了,而main没变,那我改的这个方法里面,有什么不同吗?
人家有两个字符串合并,你这就直接设置,我差点也给你蒙了,再仔细看一下代码
相关推荐
【标题】"java拼图小游戏项目tion-model-for-net开发笔记" 涉及的主要知识点是Java编程语言在游戏开发中的应用,以及可能涉及到的网络模型技术。在这个项目中,开发者可能会使用Java来创建一个简单的拼图游戏,这...
从给定文件信息来看,标题和描述中提到的《OCA Java SE 8 Programmer I Study Guide》是由Edward Finegan编写,而McGraw-Hill Education出版社出版的一本面向Oracle Certified Associate, Java SE 8 Programmer I...
从给定的文件信息来看,标题、描述以及标签均指向了“java代码基础资料”,但提供的部分内容却与IT或Java编程完全无关,而是涉及了一系列社会、经济与环境问题的论述句型,这显然与预期不符。然而,既然任务是基于...
以上知识点都是学习Java编程不可绕过的基础,是构建Java应用程序的基石。由于本书是卷一,主要侧重于基础知识的讲解,因此在进阶的卷二中,可能会涉及到更复杂的主题,如并发编程、网络编程等。然而,无论是初学者...
让我们详细探讨一下Java的核心概念和关键知识点。 1. **Java简介**: Java由Sun Microsystems开发,于1995年发布,现由甲骨文公司维护。它的设计目标是“一次编写,到处运行”,意味着编写的代码可以在任何支持...
这份资料能够帮助初学者通过亲自动手编写和运行代码,来加深对Java基础知识点的理解,如变量、数据类型、控制结构(if语句、for循环等)、函数、类和对象等。这些基础概念的掌握,对后续学习至关重要。 举个例子,...
本文将深入探讨Java的21个关键技术和知识点,旨在帮助初级和中级Java程序员巩固基础,提高技能。 首先,我们来看JVM(Java Virtual Machine)相关知识。JVM是Java程序运行的基础,理解和掌握JVM内存模型和结构至关...
【Java核心知识体系】 Java是一门广泛应用于企业级开发、移动应用及互联网领域的高级编程语言。...通过以上知识点的学习和实践,可以为Java开发者打下坚实的基础,为从事各种Java相关的开发工作做好准备。
这份文档可能包含了Java基础语法、面向对象编程概念、类与对象、继承、多态、接口、异常处理、数据类型、字符串操作、集合框架、IO流、线程以及Java虚拟机(JVM)等方面的知识点。例如,试题可能会考察你对Java...
以下是对Java开发绩效考核自评的一些关键知识点的详细阐述: 1. **工作态度和执行力**: - Java开发者应该具备良好的工作态度,如按时完成任务、遵守公司规定,对工作保持热情,遇到问题能够主动寻求解决方案,并...
【标题】"农行Java笔试题"涉及到的Java知识点涵盖了编程基础、面向对象特性、集合框架、多线程、异常处理、IO流、网络编程、数据库操作等多个领域,这些都是Java程序员必须掌握的核心技能。 首先,从编程基础角度来...
Java基础知识是编程领域中至关重要的一个部分,尤其对于初学者来说,掌握扎实的Java基础知识将为后续的进阶学习和实际开发打下坚实基础。Java作为一种广泛应用的面向对象的编程语言,其特性包括平台无关性、安全性、...
### Java面试核心知识点详解 #### 引言 随着IT行业的快速发展,Java作为一门经典且广泛应用于企业级开发的编程语言,其重要性不言而喻。对于即将步入职场的Java开发者而言,掌握一定的面试技巧及必备知识至关重要...
从压缩包中的文件名来看,我们可以推测这些文档分别涵盖了不同的辅导章节和复习题目。例如: 1. "ITAT-JAVA辅导1-10.doc"系列:这可能是按照教学进度编排的辅导材料,从1到10逐步深入,涵盖了Java的基础到进阶内容...
对于C语言的笔试题,可能会涉及到指针、内存管理、结构体、位运算、预处理指令等核心知识点。指针是C语言的灵魂,理解其工作原理和操作方式至关重要。内存管理包括动态内存分配和释放,理解堆栈和堆的区别也很关键。...
掌握以上C++、JAVA和测试领域的核心知识点,将有助于你在面试中展现出扎实的理论基础和实践经验,从而增加成功获得心仪职位的机会。记住,不断学习和实践是提升自身能力的关键,祝你在面试中取得好成绩!
下面将详细介绍Java的核心概念和技术要点,确保读者能够获得扎实的Java基础。 #### 描述解析:“看了肯定不会后悔” 这段描述虽然简单重复,但传达了一个积极的信息:本教程的内容质量很高,值得投入时间学习。接...
《Java基础36讲》作为一本Java编程入门书籍,强调了学习Java基础知识的重要性,并由四川大学研究生学长根据自己学习Java的心得体会,编撰而成,旨在为零基础同学和非计算机专业同学提供自学材料。该书详细地介绍了...
Java语言概述通常包括以下几个关键知识点: 1. **Java历史与特点**:介绍Java的发展历程,由Sun Microsystems(现已被Oracle收购)创建,强调其跨平台的特性,即“一次编写,到处运行”。 2. **Java环境配置**:...
从读者的反馈来看,《Thinking in Java》不仅覆盖了Java的核心概念和技术,还通过一系列富有挑战性的练习帮助读者深入理解和掌握这些知识。下面我们将根据提供的文件信息来详细阐述该书中的关键知识点。 ### 一、...