- 浏览: 586192 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (365)
- Tomcat调优 (2)
- Apache Http (20)
- Webserver安装 (5)
- Linux安装 (28)
- Linux常用命令 (17)
- C语言及网络编程 (10)
- 文件系统 (0)
- Lucene (12)
- Hadoop (9)
- FastDFS (8)
- 报表 (0)
- 性能测试 (1)
- JAVA (18)
- CSharp (3)
- C++ (38)
- BI (0)
- 数据挖掘 (0)
- 数据采集 (0)
- 网址收集整理 (3)
- Resin (0)
- JBoss (0)
- nginx (0)
- 数据结构 (1)
- 随记 (5)
- Katta (1)
- Shell (6)
- webservice (0)
- JBPM (2)
- JQuery (6)
- Flex (41)
- SSH (0)
- javascript (7)
- php (13)
- 数据库 (6)
- 搜索引擎排序 (2)
- LVS (3)
- solr (2)
- windows (1)
- mysql (3)
- 营销软件 (1)
- tfs (1)
- memcache (5)
- 分布式搜索 (3)
- 关注的博客 (1)
- Android (2)
- clucene (11)
- 综合 (1)
- c c++ 多线程 (6)
- Linux (1)
- 注册码 (1)
- 文件类型转换 (3)
- Linux 与 asp.net (2)
- perl (5)
- coreseek (1)
- 阅读器 (2)
- SEO (1)
- 励志 (1)
- 在线性能测试工具 (1)
- yii (7)
- 服务器监控 (1)
- 广告 (1)
- 代理服务 (5)
- zookeeper (8)
- 广告联盟 (0)
- 常用软件下载 (1)
- 架设自已的站点心得 (0)
最新评论
-
terry07:
java 7 用这个就可以了 Desktop desktop ...
关于java Runtime.getRunTime.exec(String command)的使用 -
HSINKING:
怎么设置打开的dos 窗口是指定的路径下
关于java调用bat文件,不打开窗口 -
liubang201010:
hyperic hq更多参考资料,请访问:http://www ...
hyperic-hq -
^=^:
STDIN_FILENO是unistd.h中定义的一个numb ...
深入理解dup和dup2的用法 -
antor:
留个记号,学习了
[转]用java流方式判断文件类型
from http://blog.csdn.net/bitfan/archive/2010/12/18/6083926.aspx
引用
北理工Java技术与应用考试试题参考答案及点评(上) 收藏 此文于2010-12-21被推荐到CSDN首页
如何被推荐?
北理工 Java 技术与应用考试试题参考答案及点评(上)
注:
自从我在前一篇博文《 自测一下你的 Java掌握得怎么样? 》中贴出了我给北京理工大学计算机学院 2008 级学生设计的 Java 试题之后,出乎意料,引发了朋友的兴趣,回贴众多,还有部分热心朋友提供了部分试题的答案。
作为这套试题的设计者,我觉得我应该比较详细地剖析一下这套试题,而且我相信关注这套试题的朋友中,在校学生应该有不少,因此,我将针对在校学生的特点来点评,期望能帮助这些学生更有效地学习。
为节省篇幅,仅对部分题目予以点评,那些比较简单的查查书就能得到答案的题目,本文略过。尽管如此,文章还是太长,所以分成两部分贴出。
另外,部分题目是主观题,见仁见智,我给出的答案仅为参考。
答案及点评以红色标出。
由于本人才疏学浅,这些答案中如有错误,也敬请业界朋友或其他学校的教师指出,如果确认是我对技术的理解有误,我也将调整为学生给出的分数。
谢谢大家!
金旭亮
2010 年 12 月 18 日
附注:
CSDN的博客系统太差了,老出错,发博文花的时间比我写博文还长!
=================================================================================
一、判断题(正确的描述打钩,错误的打叉,每题 1 分,共 10 分)
1. 一个 Java 源文件中只能定义一个公有类,并且类名必须与文件名一致。(对)
2. 通过在程序中引入“ import javax.swing.*; ”语句,就可以使用 javax.swing 包中的所有类(包括其嵌套的子包中的类)。 (错)
要使用嵌套子包中的类,必须再次添加 import 子句
3. J2SE 的功能是 J 2 ME 的一个子集。(错)
4. Java 字节码只有被装入到内存中之后,才能被执行。(对)
在当前计算机体系结构之下,CPU无法直接读取保存于磁盘上的程序文件,这些文件所包容的指令必须被装入到内存之后,CPU才能读取。
5. Swing是一套GUI组件,采用了新的思路设计Java应用程序的界面,它完全地替换掉了原有的AWT。(错)
Swing仍然使用AWT的事件模型,并非完全抛弃。
值得注意的NetBeans 6.9.1完成最新的更新组件后,创建Java桌面应用程序时,有了一个新的提示消息框:
看来Oracle也知道Java在桌面上没戏,干脆放弃了对Swing框架的进一步开发。已经存在这么多年的Swing框架被“新主人”抛弃,真不知道该说什么。
6. 在编程时编写过多的注释,会使编译之后生成的程序文件变大。(错)
放心, 编译器会删除所有的注释。所以,哪怕你在程序中写了一部长篇小说,也不会拖慢程序的运行速度。
7. Java Applet 可运行于浏览器中,这意味着浏览器本身就可以直接执行 Applet 程序。(错)
浏览器本身只认识HTML,它对其他类型信息的支持,比如Flash,Applet,Silverlight应用程序等都是通过启动本地计算机安装的附加插件来实现的。
8. JDK 5.0新增的枚举类型( enum )是一个原始数据类型。(错)
9. Java 中规定所有的方法都必须放到某个类中,不存在独立于类的方法。(对)
10. 面向对象软件系统设计师们经常用到的 UML 是一种编程语言。(错)
二、简答题(请将答案写到答题纸上,注明题号。每题 4 分,共 40 分)
1. 现代编程语言有两种主要的类型:一种是“编译型 ”的,比如 C ,程序源码必须经过编译才能运行;另一种是“解释型 ”的,这种类型的语言(比如早期的 Basic )通常都拥有一个交互环境,用户输入一句代码计算机就执行一句代码。
Java 属于上述哪种类型?如果你认为 Java 不属于上述任何一种类型,那么它是不是一种新的编程语言类型?
Java源程序需要编译,但运行时需要即时“解释”为本地CPU能执行的机器指令,所以它不属于“纯”的编译型或解释型,而是一种混合类型。
有的同学很“绝”,他说:“Java是一种面向对象类型的编程语言”。这句话还真是对的,我也给了分。
2. Java 中有两个关键字: void 和 null ,它们有什么区别?
这题100%的学生都能答对,纯粹是送分题。
3. 简述“类(Class)”、“类库(Class Library)”、“包(Package)”、“ Jar 文件”这四个概念间的联系。
类库其实是一个“统称”,它是类的集合。包则是类库的组织形式,它类似于C++中的namespace,可以解决类的同名问题。
Jar则是一个采用Zip格式压缩的文件包 ,主要是为了方便Java组件的复用,简化Java应用程序的部署和发布。Jar包中可以保存任意类型的多个文件和多级嵌套的文件夹。比如JDK就包容了不少Jar压缩包,你可以使用解压缩工具(比如WinRAR)去查看它的内容。可以把Jar文件看成是Java类库的一个物理“载体”,之所以称其为“物理”的,是因为我们可以在计算机中直接“看见”并“操作”它。
在学习和探索知识的过程中,有的时候就必须注意清晰地分清各个似是而非的概念,这道题有好几个同学就把这几个概念间的关系弄乱了。
4. 面向对象的程序在运行时会创建多个对象,这些对象之间通常可以相互 “ 发送消息 ” ,谈谈你对 “ 对象之间发送消息 ” 这句话的理解,并编写若干句示例代码展示对象之间发送消息的具体编程实现方法。
对象间的消息发送最基本的手段就是:一个对象执有另一个对象的引用,然后,通这个对象引用调用对方的方法,存取对方的字段(或属性)。
对象互发消息,其本质目的就是为了交换信息。
除了上述这两种直接方式之外,我们还可以通过一些第三方的媒价来实现对象间的信息交换:比如利用类的静态字段,利用内存映射文件,利用数据库,利用外部共享的“物理”文件等。
我在《.NET 4.0面向对象编程漫谈 》的第14章《对象间的协作与信息交换》中介绍了七八种单个、多个对象间消息发送和信息交换的方式,虽然是用C#实现的,但其思想完全可用于Java中。
掌握这些编程技巧,对开发非常关键。
5. 加法运算符“+”可以施加于原始数值类型(比如 int )的变量,但我们发现一些对象类型(比如 Integer ) 的变量,也支持“+”运算:
Integer v1 = 100;
Integer v2 = 200;
System.out.println(v1+v2 ); //输出: 300
这看上去好象 Integer 类型重载了 “ + ” 法运算符,一些编程语言比如 C ++可以为特定的类重载运算符,但 Java 本身并不支持运算符重载这一特性。依你的理解或猜测, Java 是采用什么方法让两个 Integer 对象可以直接“相加”的?
上面代码首先是调用Integer.valueOf方法将整数转换为Integer对象,当两个Integer对象相加时,其实是使用Integer.intValue方法取出其所“包装”的整数值,相加之后,再将结果输出。
上述结论是通过分析javap反汇编示例代码得到的。
诸如Java和C#之类的编程语言,许多现象已不仅仅是语法问题,编译器在其中起了很重要的作用。我在课堂上已经介绍过如何使用javap去反汇编.class文件,通过阅读Java编译器生成的字节码指令去弄明白java编译器在后台玩的把戏。
这道题主要是引导学生学编程语言不要仅学语法,要学会利用工具透过表面现象看本质。
有的学生猜测Java可能是设计了另外的对象负责完成“+”运算,虽然与Java实际情况不符,但这个思路是可行的,我同样给分。
6. 在一个很大的循环(比如循环10000000 次)中,如果需要进行字串的连接操作,通常我们者使用StringBuffer 取代String ,解释这么做的理由。
绝大部分同学都答对了。但有的同学说:在大循环中使用String,会“浪费”大量的内存,这句话是不准确的,因为Java有一个垃圾收集机制,在合适的时机会出来回收不用的String对象,因此,这些内存不能说是被“浪费”的,我们唯一可以说的是:
由于String对象是只读的,使用它大量字串连接操作,将导致频繁的内存分配操作 ,这会严重地影响程序性能。
7. 现有两个长度不同的数组:
int[] arr1 = new int[10];
int[] arr2 = new int[100];
那么以下语句能通过编译吗?
arr1 = arr2;
如果你认为可以通过编译,得到这个结论的依据是什么?如果不能通过编译,你认为其原因是什么?
可以通过编译。此题考核学生知不知道 Java 中的数组属于对象类型,知不知道对象变量相互赋值的含义。
8. 请看以下代码 :
double d1=100.1;
double d2=1001/10;
System.out.println(d1==d2); // 输出 : false
明明 d1 与 d2 是相等的 , 为什么程序运行时会输出一个让人意外的结果 : false ?
很多同学都指出1001/10 其实是“整除”,得到100 ,再转为double ,所以d2=100.0 ,自然d1==d2 返回false 了。
由于我在课堂上曾展示过计算机难于精确表示双精度数,比较两个double 变量是否相等应该检测其差的绝对值是否在某个可以容忍的误差范围内,所以几个同学就往这个思路上去想了。
对这种情况,我没扣分。
9. 当使用多个 catch 语句捕获多个异常时, Java 规定捕获 Exception 的 catch 语句必须排在最后,如下所示:
try { …… }
catch(ClassCastException ex){…… }
catch(NumberFormatException ex){…… }
catch(Exception ex){ …… } // 此句必须放在最后!
为什么会有这个限制?谈谈你是怎么理解的。
学生们几乎 100% 答对此题,由于 Exception 是顶层类,放到前面会导致后面的 catch 语句不可能有机会运行。
10. 请看以下示例代码:
String s1 = "Hello";
String s2 = "Hello";
System.out.println(s1 == s2); // 输出: true
String s3 = new String("Hello");
String s4 = new String("Hello");
System.out.println(s3 == s4); // 输出: false
请解释一下为什么上述代码中 “ System.out …” 两句代码输出完全不同的结果 ?
这里面的关键在于 Java 常量池。 JVM 在装载一个 .class 文件时,会在内存中创建一个常量池。
“ Hello ”是字符串常量, Java 编译器会将“ Hello ”放到常量池中,并给它一个索引:
const #28 = Asciz Hello;
以下两句代码:
String s1 = "Hello";
String s2 = "Hello";
将生成以下的字节码指令:
0: ldc #2; //String Hello
2: astore_1
3: ldc #2; //String Hello
5: astore_2
上面的 #2 代表常量池中的第 2 项:
const #2 = String #28; // Hello
注意它引用常量池的第 28 项,前面已经看到,第 28 项就是一个“ Hello ”字符串对象。
astore 指令将常量池中同一个“ Hello ”字符串对象的地址赋给了 s1 和 s2 ,所以, s1==s2 肯定返回 true 。
下面来看一下:
String s3 = new String("Hello");
所生成的字节码指令:
// 创建 String 对象,对象引用被 Push 到操作数堆栈( operand stack )
// 常量池的第 5 项指向一个 CONSTANT_Class_info 类型的表项,这个表项将引用 String 类型
// 在程序运行时,会导致 JVM 装载并连接 String 类型信息
22: new #5; //class java/lang/String
25: dup // 复制对象引用,再次压入操作数堆栈,此复制的对象引用将用于调用构造函数
26: ldc #2; //String Hello 装载常量“ Hello ”
28: invokespecial #6;
//Methodjava/lang/String."<init>":(Ljava/lang/String;)V
// 调用 String 类的构造函数,它从操作数堆栈提取信息初始化 String 对象
31: astore_3 // 将创建好的对象引用保存到 s3 中
从上述分析可以清晰地看到, s3 与 s4 都引用不同的对象。所以, s3==s4 返回 fasle 。
现在,同学们对 JVM 的认识是不是更深入了一步?
现在 Java 程序员“遍地”都是,但其中高水平的不多,为什么?
一个很重要的原因就是浅尝辄止,仅记住了一些语法结论,却从不主动地去探索一下代码背后的奥秘,怎会有提高?
我很早就在课堂上展示了 javap 的使用方法,并向同学们推荐了那本经典的《 Inside the Java Virtual Machine 》,但我估计由于课业负担重,没几个同学真的去看了这本书,对此,我只能一声叹息。
多问几个为什么,对事物刨根问底,这其实不是在学习,而是在探索了,这个过程中,你的能力会得到不断地锻炼和提高。
另外我要指出,同样的学习方法可以直接用 .NET 领域,比如 .NET 有一个 ildasm 可以直接查看 .NET 程序集( .exe 和 .dll ,等价于 Java 中的 .class )中的 IL 指令(对应于 Java 字节码指令),有一个 Reflector 工具可以很方便地反汇编查看任意一个程序集的源码,对应地, .NET 虚拟机—— CLR ,也与 JVM 有许多相似之处。
我在写作《 .NET 4.0 面向对象编程漫谈》时,就通过直接查看程序集的 IL 指令代码,弄清楚了不少东西,也加深了对语言编译器和虚拟机的认识。
象 Java 和 .NET 这种非常相近的平台,下功夫弄清楚一个,你会发现学习与掌握另一个并不困难。计算机有很多东西是相通的。关键不在于学什么东西,而是是否掌握了学习的科学方法,并且有一种不断学习、勇于探索未知的精神。具备这种基本素质的学生,我相信他日后的发展应该不会差的。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/bitfan/archive/2010/12/18/6083926.aspx
如何被推荐?
北理工 Java 技术与应用考试试题参考答案及点评(上)
注:
自从我在前一篇博文《 自测一下你的 Java掌握得怎么样? 》中贴出了我给北京理工大学计算机学院 2008 级学生设计的 Java 试题之后,出乎意料,引发了朋友的兴趣,回贴众多,还有部分热心朋友提供了部分试题的答案。
作为这套试题的设计者,我觉得我应该比较详细地剖析一下这套试题,而且我相信关注这套试题的朋友中,在校学生应该有不少,因此,我将针对在校学生的特点来点评,期望能帮助这些学生更有效地学习。
为节省篇幅,仅对部分题目予以点评,那些比较简单的查查书就能得到答案的题目,本文略过。尽管如此,文章还是太长,所以分成两部分贴出。
另外,部分题目是主观题,见仁见智,我给出的答案仅为参考。
答案及点评以红色标出。
由于本人才疏学浅,这些答案中如有错误,也敬请业界朋友或其他学校的教师指出,如果确认是我对技术的理解有误,我也将调整为学生给出的分数。
谢谢大家!
金旭亮
2010 年 12 月 18 日
附注:
CSDN的博客系统太差了,老出错,发博文花的时间比我写博文还长!
=================================================================================
一、判断题(正确的描述打钩,错误的打叉,每题 1 分,共 10 分)
1. 一个 Java 源文件中只能定义一个公有类,并且类名必须与文件名一致。(对)
2. 通过在程序中引入“ import javax.swing.*; ”语句,就可以使用 javax.swing 包中的所有类(包括其嵌套的子包中的类)。 (错)
要使用嵌套子包中的类,必须再次添加 import 子句
3. J2SE 的功能是 J 2 ME 的一个子集。(错)
4. Java 字节码只有被装入到内存中之后,才能被执行。(对)
在当前计算机体系结构之下,CPU无法直接读取保存于磁盘上的程序文件,这些文件所包容的指令必须被装入到内存之后,CPU才能读取。
5. Swing是一套GUI组件,采用了新的思路设计Java应用程序的界面,它完全地替换掉了原有的AWT。(错)
Swing仍然使用AWT的事件模型,并非完全抛弃。
值得注意的NetBeans 6.9.1完成最新的更新组件后,创建Java桌面应用程序时,有了一个新的提示消息框:
看来Oracle也知道Java在桌面上没戏,干脆放弃了对Swing框架的进一步开发。已经存在这么多年的Swing框架被“新主人”抛弃,真不知道该说什么。
6. 在编程时编写过多的注释,会使编译之后生成的程序文件变大。(错)
放心, 编译器会删除所有的注释。所以,哪怕你在程序中写了一部长篇小说,也不会拖慢程序的运行速度。
7. Java Applet 可运行于浏览器中,这意味着浏览器本身就可以直接执行 Applet 程序。(错)
浏览器本身只认识HTML,它对其他类型信息的支持,比如Flash,Applet,Silverlight应用程序等都是通过启动本地计算机安装的附加插件来实现的。
8. JDK 5.0新增的枚举类型( enum )是一个原始数据类型。(错)
9. Java 中规定所有的方法都必须放到某个类中,不存在独立于类的方法。(对)
10. 面向对象软件系统设计师们经常用到的 UML 是一种编程语言。(错)
二、简答题(请将答案写到答题纸上,注明题号。每题 4 分,共 40 分)
1. 现代编程语言有两种主要的类型:一种是“编译型 ”的,比如 C ,程序源码必须经过编译才能运行;另一种是“解释型 ”的,这种类型的语言(比如早期的 Basic )通常都拥有一个交互环境,用户输入一句代码计算机就执行一句代码。
Java 属于上述哪种类型?如果你认为 Java 不属于上述任何一种类型,那么它是不是一种新的编程语言类型?
Java源程序需要编译,但运行时需要即时“解释”为本地CPU能执行的机器指令,所以它不属于“纯”的编译型或解释型,而是一种混合类型。
有的同学很“绝”,他说:“Java是一种面向对象类型的编程语言”。这句话还真是对的,我也给了分。
2. Java 中有两个关键字: void 和 null ,它们有什么区别?
这题100%的学生都能答对,纯粹是送分题。
3. 简述“类(Class)”、“类库(Class Library)”、“包(Package)”、“ Jar 文件”这四个概念间的联系。
类库其实是一个“统称”,它是类的集合。包则是类库的组织形式,它类似于C++中的namespace,可以解决类的同名问题。
Jar则是一个采用Zip格式压缩的文件包 ,主要是为了方便Java组件的复用,简化Java应用程序的部署和发布。Jar包中可以保存任意类型的多个文件和多级嵌套的文件夹。比如JDK就包容了不少Jar压缩包,你可以使用解压缩工具(比如WinRAR)去查看它的内容。可以把Jar文件看成是Java类库的一个物理“载体”,之所以称其为“物理”的,是因为我们可以在计算机中直接“看见”并“操作”它。
在学习和探索知识的过程中,有的时候就必须注意清晰地分清各个似是而非的概念,这道题有好几个同学就把这几个概念间的关系弄乱了。
4. 面向对象的程序在运行时会创建多个对象,这些对象之间通常可以相互 “ 发送消息 ” ,谈谈你对 “ 对象之间发送消息 ” 这句话的理解,并编写若干句示例代码展示对象之间发送消息的具体编程实现方法。
对象间的消息发送最基本的手段就是:一个对象执有另一个对象的引用,然后,通这个对象引用调用对方的方法,存取对方的字段(或属性)。
对象互发消息,其本质目的就是为了交换信息。
除了上述这两种直接方式之外,我们还可以通过一些第三方的媒价来实现对象间的信息交换:比如利用类的静态字段,利用内存映射文件,利用数据库,利用外部共享的“物理”文件等。
我在《.NET 4.0面向对象编程漫谈 》的第14章《对象间的协作与信息交换》中介绍了七八种单个、多个对象间消息发送和信息交换的方式,虽然是用C#实现的,但其思想完全可用于Java中。
掌握这些编程技巧,对开发非常关键。
5. 加法运算符“+”可以施加于原始数值类型(比如 int )的变量,但我们发现一些对象类型(比如 Integer ) 的变量,也支持“+”运算:
Integer v1 = 100;
Integer v2 = 200;
System.out.println(v1+v2 ); //输出: 300
这看上去好象 Integer 类型重载了 “ + ” 法运算符,一些编程语言比如 C ++可以为特定的类重载运算符,但 Java 本身并不支持运算符重载这一特性。依你的理解或猜测, Java 是采用什么方法让两个 Integer 对象可以直接“相加”的?
上面代码首先是调用Integer.valueOf方法将整数转换为Integer对象,当两个Integer对象相加时,其实是使用Integer.intValue方法取出其所“包装”的整数值,相加之后,再将结果输出。
上述结论是通过分析javap反汇编示例代码得到的。
诸如Java和C#之类的编程语言,许多现象已不仅仅是语法问题,编译器在其中起了很重要的作用。我在课堂上已经介绍过如何使用javap去反汇编.class文件,通过阅读Java编译器生成的字节码指令去弄明白java编译器在后台玩的把戏。
这道题主要是引导学生学编程语言不要仅学语法,要学会利用工具透过表面现象看本质。
有的学生猜测Java可能是设计了另外的对象负责完成“+”运算,虽然与Java实际情况不符,但这个思路是可行的,我同样给分。
6. 在一个很大的循环(比如循环10000000 次)中,如果需要进行字串的连接操作,通常我们者使用StringBuffer 取代String ,解释这么做的理由。
绝大部分同学都答对了。但有的同学说:在大循环中使用String,会“浪费”大量的内存,这句话是不准确的,因为Java有一个垃圾收集机制,在合适的时机会出来回收不用的String对象,因此,这些内存不能说是被“浪费”的,我们唯一可以说的是:
由于String对象是只读的,使用它大量字串连接操作,将导致频繁的内存分配操作 ,这会严重地影响程序性能。
7. 现有两个长度不同的数组:
int[] arr1 = new int[10];
int[] arr2 = new int[100];
那么以下语句能通过编译吗?
arr1 = arr2;
如果你认为可以通过编译,得到这个结论的依据是什么?如果不能通过编译,你认为其原因是什么?
可以通过编译。此题考核学生知不知道 Java 中的数组属于对象类型,知不知道对象变量相互赋值的含义。
8. 请看以下代码 :
double d1=100.1;
double d2=1001/10;
System.out.println(d1==d2); // 输出 : false
明明 d1 与 d2 是相等的 , 为什么程序运行时会输出一个让人意外的结果 : false ?
很多同学都指出1001/10 其实是“整除”,得到100 ,再转为double ,所以d2=100.0 ,自然d1==d2 返回false 了。
由于我在课堂上曾展示过计算机难于精确表示双精度数,比较两个double 变量是否相等应该检测其差的绝对值是否在某个可以容忍的误差范围内,所以几个同学就往这个思路上去想了。
对这种情况,我没扣分。
9. 当使用多个 catch 语句捕获多个异常时, Java 规定捕获 Exception 的 catch 语句必须排在最后,如下所示:
try { …… }
catch(ClassCastException ex){…… }
catch(NumberFormatException ex){…… }
catch(Exception ex){ …… } // 此句必须放在最后!
为什么会有这个限制?谈谈你是怎么理解的。
学生们几乎 100% 答对此题,由于 Exception 是顶层类,放到前面会导致后面的 catch 语句不可能有机会运行。
10. 请看以下示例代码:
String s1 = "Hello";
String s2 = "Hello";
System.out.println(s1 == s2); // 输出: true
String s3 = new String("Hello");
String s4 = new String("Hello");
System.out.println(s3 == s4); // 输出: false
请解释一下为什么上述代码中 “ System.out …” 两句代码输出完全不同的结果 ?
这里面的关键在于 Java 常量池。 JVM 在装载一个 .class 文件时,会在内存中创建一个常量池。
“ Hello ”是字符串常量, Java 编译器会将“ Hello ”放到常量池中,并给它一个索引:
const #28 = Asciz Hello;
以下两句代码:
String s1 = "Hello";
String s2 = "Hello";
将生成以下的字节码指令:
0: ldc #2; //String Hello
2: astore_1
3: ldc #2; //String Hello
5: astore_2
上面的 #2 代表常量池中的第 2 项:
const #2 = String #28; // Hello
注意它引用常量池的第 28 项,前面已经看到,第 28 项就是一个“ Hello ”字符串对象。
astore 指令将常量池中同一个“ Hello ”字符串对象的地址赋给了 s1 和 s2 ,所以, s1==s2 肯定返回 true 。
下面来看一下:
String s3 = new String("Hello");
所生成的字节码指令:
// 创建 String 对象,对象引用被 Push 到操作数堆栈( operand stack )
// 常量池的第 5 项指向一个 CONSTANT_Class_info 类型的表项,这个表项将引用 String 类型
// 在程序运行时,会导致 JVM 装载并连接 String 类型信息
22: new #5; //class java/lang/String
25: dup // 复制对象引用,再次压入操作数堆栈,此复制的对象引用将用于调用构造函数
26: ldc #2; //String Hello 装载常量“ Hello ”
28: invokespecial #6;
//Methodjava/lang/String."<init>":(Ljava/lang/String;)V
// 调用 String 类的构造函数,它从操作数堆栈提取信息初始化 String 对象
31: astore_3 // 将创建好的对象引用保存到 s3 中
从上述分析可以清晰地看到, s3 与 s4 都引用不同的对象。所以, s3==s4 返回 fasle 。
现在,同学们对 JVM 的认识是不是更深入了一步?
现在 Java 程序员“遍地”都是,但其中高水平的不多,为什么?
一个很重要的原因就是浅尝辄止,仅记住了一些语法结论,却从不主动地去探索一下代码背后的奥秘,怎会有提高?
我很早就在课堂上展示了 javap 的使用方法,并向同学们推荐了那本经典的《 Inside the Java Virtual Machine 》,但我估计由于课业负担重,没几个同学真的去看了这本书,对此,我只能一声叹息。
多问几个为什么,对事物刨根问底,这其实不是在学习,而是在探索了,这个过程中,你的能力会得到不断地锻炼和提高。
另外我要指出,同样的学习方法可以直接用 .NET 领域,比如 .NET 有一个 ildasm 可以直接查看 .NET 程序集( .exe 和 .dll ,等价于 Java 中的 .class )中的 IL 指令(对应于 Java 字节码指令),有一个 Reflector 工具可以很方便地反汇编查看任意一个程序集的源码,对应地, .NET 虚拟机—— CLR ,也与 JVM 有许多相似之处。
我在写作《 .NET 4.0 面向对象编程漫谈》时,就通过直接查看程序集的 IL 指令代码,弄清楚了不少东西,也加深了对语言编译器和虚拟机的认识。
象 Java 和 .NET 这种非常相近的平台,下功夫弄清楚一个,你会发现学习与掌握另一个并不困难。计算机有很多东西是相通的。关键不在于学什么东西,而是是否掌握了学习的科学方法,并且有一种不断学习、勇于探索未知的精神。具备这种基本素质的学生,我相信他日后的发展应该不会差的。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/bitfan/archive/2010/12/18/6083926.aspx
发表评论
-
通过JVM获取相关的服务器信息 .
2012-02-02 14:24 1154分类: j2ee 2009-05-12 16:12 1034人 ... -
JVM调优总结 -Xms -Xmx -Xmn -Xss
2011-11-10 09:15 7712009-03-05 JVM调优总结 -Xms -Xmx - ... -
关于java Runtime.getRunTime.exec(String command)的使用
2011-10-19 19:31 91342008-09-26 19:44当要调用一个外部程序的时候,j ... -
关于java调用bat文件,不打开窗口
2011-10-19 19:31 2181Runtime.getRuntime().exec(" ... -
Runtime.getRuntime().exec(cmd) cd
2011-10-19 18:49 2865BashLinux.如果要在java程序里执行一条linux可 ... -
11款用于优化、分析源代码的Java工具
2011-08-03 09:16 634from http://java.csdn.net/a/201 ... -
用java实现html转pdf
2011-02-28 12:58 6660import java.io.File; import ja ... -
[转]用java流方式判断文件类型
2011-02-28 11:46 2513文章分类:Java编程 今天在群里面看有人贴的一个帖子,觉 ... -
jodconverter纯文本文件转为pdf时中文问题解决方案
2011-02-28 11:28 2032文章分类:Java编程 jodconverter转换ms文 ... -
利用OpenOffice将word转换成PDF
2011-02-28 11:00 3097引用文章分类:Java编程 之前找了一种方式是通过jacob ... -
老紫竹JAVA提高教程-信号量(Semaphore)在生产者和消费者模式的使用
2011-02-14 17:07 2075Semaphore 信号量,就是一个允许实现设置好的令牌。也许 ... -
北理工Java技术与应用考试试题参考答案及点评(下)
2011-01-24 12:12 987from :http://blog.csdn.net/bitf ... -
自测一下你的Java掌握得怎么样
2011-01-24 12:10 861引用自测一下你的Java掌握得怎么样? ========= ... -
Java执行脚本代码分析
2011-01-21 16:46 1275Java, 执行脚本 1、可用的脚本引擎 Java 6 ... -
java开发守护进程
2011-01-11 13:29 1203其实就是想开发个Windows下系统服务一样的程序。而查了好久 ... -
JDK5.0垃圾收集优化
2010-09-08 10:37 712JDK5.0垃圾收集优化(转 ... -
volatile 变量使用指南
2010-06-10 10:40 762Java 理论与实践: 正确使 ...
相关推荐
文件标题:“北京理工大学《计算机组成原理》期末考试试卷(含答案).pdf”与描述:“北京理工大学《组成原理》期末考试试卷(含答案)”暗示了以下知识点内容,这应当是一份涵盖了计算机硬件组成原理的考试试卷。...
该部分内容似乎是OCR扫描技术产生的错误或无法识别的文字,无法提供有关“北京理工大学《物理化学》考试试卷”的具体知识点。 不过,考虑到您请求的是关于“物理化学”考试试卷的知识点,我可以从《物理化学》这门...
根据给定的文件信息,这份文档是北京理工大学《大学物理上》09到15年历年期末考试试卷(含答案)。这份文档是物理学领域的资料,涵盖的年份跨度为7年,包含了试题和对应的答案。此类资料对于学习物理学,尤其是大学...
从提供的文件内容来看,这是北京理工大学在2007-2014年期间历年的《电工与电子技术I》期末试题,包括试题和答案。这些试题覆盖了直流电路分析、交流电路分析、电路的功率计算、三相交流电路、谐振电路、戴维宁定理的...
北京理工大学的《电力电子技术》课程练习试题涉及了电力电子领域中的一些核心概念和技术,从这些练习题中,我们可以提炼出如下知识点: 1. 电力电子器件简称为电力半导体器件,包括电力晶体管GTR、功率MOSFET、复合...
北京理工大学的《线性代数A》历年期末考试试卷中涵盖了线性代数的多个核心知识点,包括矩阵运算、线性方程组、特征值与特征向量、线性相关与无关、向量空间、基与维数、正交变换、二次型、正定性以及线性映射等。...
描述部分的“北京理工大学《数据结构》期末试卷(含答案)”进一步强调了文件内容与数据结构课程相关,并且包含了考试的参考答案,这对于准备考试的学生来说是非常有用的资料。 标签部分中的“数据结构”是这份文档...
在21春北京理工大学的《Java技术与应用》课程中,学生可能会接触到一系列Java编程的基础概念和实践技能。以下是一些相关的知识点: 1. **Java编译器**:Java程序的编译是由`javac`命令完成的,它将源代码(.java...
在分析北京理工大学《复变函数与积分变换》历年期末考试试卷的内容时,我们可以从中提取出以下知识点: 1. 复数和复平面:试卷中出现了多种涉及复数的问题,如求复数区域在特定映射下的像,以及讨论复函数在复平面...
北京理工大学作为国内的重点高等学府,在教学和考试内容上都会非常注重对学生基础知识和抽象思维能力的培养。 根据提供的文件信息,《离散数学》期末考试题和答案的PDF文件中包含了大量的重复词汇“创创大帝”,...
北京理工大学的《信号与系统》课程是一门重要的电子信息类专业基础课,它涵盖了信号与系统的基本理论和分析方法。在进行期末复习时,需要深入理解以下几个方面的主要知识点: 1. 线性时不变系统(LTI系统)的基本...
微机原理与接口技术_期末考试试题答案4.pdf
计算机导论期末考试试题及答案.pdf 中包含了计算机导论的重要知识点,涵盖了计算机应用、分类、数据表示、逻辑运算、计算机系统结构、存储器、输入/输出设备、计算机性能指标等方面。 1. 计算机应用:客机、火车...
《北京林业大学历年高等数学A下学期期末考试试卷解析》 高等数学,作为理工科学生的基础课程,其重要性不言而喻。北京林业大学的高等数学A课程,以其严谨的学术风格和全面的知识覆盖,对学生的逻辑思维与计算能力...
综上所述,北京理工大学《人工智能》研究生期末试题涵盖了人工智能领域内多个重要的理论和应用问题,考察了学生对于相关知识点的理解和应用能力。通过对这些题目进行研究和解答,能够深入理解人工智能的核心原理,并...
北京理工大学的《汇编语言》是一门深入研究计算机基础指令集、程序设计和计算机工作原理的专业课程。从提供的文件片段来看,包含了多个汇编语言相关的习题及其答案,主要涉及了寻址方式、指令执行、物理地址计算以及...
从标题“北京理工大学《工科数学分析II》05-15年历年期末考试试卷(含答案)”可以得知,这是一份包含从2005年至2015年所有历年期末考试试题及答案的试卷集。 从提供的【部分内容】来看,文档中的文字似乎并没有...
综上所述,北京理工大学《数字电子技术基础》期末复习试卷资料涉及了数字电路设计中的众多关键知识点,包括逻辑运算化简、基本门电路应用、存储器容量计算、译码器和数据选择器的应用、555定时器设计、计数器设计等...
在物理学科的探索旅程中,北京理工大学的《大学物理》下试卷2015-2016参考答案无疑是一座引导学生深化理解的灯塔。该试卷的出现不仅对当年参与考试的学生起到了回顾和检验学习成果的作用,也为后来学习物理学的学生...