当前位置:文档之家› Java程序安全检查工具前端的设计与实现

Java程序安全检查工具前端的设计与实现

Java程序安全检查工具前端的设计与实现
Java程序安全检查工具前端的设计与实现

西安电子科技大学

硕士学位论文

Java程序安全检查工具前端的设计与实现

姓名:王坤

申请学位级别:硕士

专业:计算机软件与理论

指导教师:刘坚

20100101

摘要

本文在分析程序安全检查工具框架的基础上,根据安全检查的特殊需求,给出了一种基于ASM(一种字节码分析工具)构造Java安全检查器前端的方法,并将此方法应用于实际开发过程中。使用此方法构造的前端通过分析Java字节码文件为后端安全检查提供符号表、抽象语法树。

文中重点讨论了符号表和抽象语法树的设计与实现。首先,本文针对字节码文件中符号和作用域的特点,设计了适用于Java字节码文件的符号表。其次,针对如何从字节码文件中恢复出表达式和控制流语句结构的问题,设计了模拟字节码指令执行的方法。该方法通过模拟字节码指令的实际执行过程,提取出建立抽象语法树所需的信息,生成抽象语法树。

关键词:安全检查 符号表 抽象语法树 J a v a字节码 字节码分析工具

A B S T R A C T

According to the specific requirements for the safety check, a method based on a Java bytecode file analyzer ASM, for constructing the front-end of a Java program safety checker is proposed and implemented in this thesis. The front-end provides symbol table and abstract syntax tree for the back-end of the safety checker by analyzing Java bytecode files of the project.

The design and implementation of the symbol table and abstract syntax tree are detailedly discussed in the thesis. Firstly, according to the feature of the symbol name and scope in Java bytecode file, an adaptive, extensible symbol table is presented in this thesis. Secondly, a method which gains the abstract syntax tree from Java bytecode files is proposed in this thesis. This method simulates the Java bytecode execution to get the information which is used to build the abstract syntax tree.

Keyword: Safety check Symbol Table Abstract Syntax Tree

Java Bytecode Bytecode file analyzer

创新性声明

本人声明所呈交的论文是我个人在导师的指导下进行的研究工作及取得的研究成果。尽我所知,除了文中特别加以标注和致谢中所罗列的内容以外,论文中不包含其它人已经发表或撰写过的研究成果,也不包含为获得西安电子科技大学或其它教育机构的学位或证书而使用过的材料。与我一同工作的同志对本研究工作所做的任何贡献均已在论文中作了明确的说明并表示了谢意。

申请学位论文若有不实之处,本人承担一切相关责任。

本人签名:日期:

关于论文使用授权的说明

本人完全了解西安电子科技大学有关保留和使用学位论文的规定,即:研究生在校攻读学位期间论文工作的知识产权单位属西安电子科技大学。本人保证毕业离校后,发表论文或使用论文工作成果时署名单位仍然为西安电子科技大学。学校有权保留送交论文的复印件,允许查阅和借阅论文;学校可以公布论文的全部或部分内容,可以允许采用影印、缩印或其它复制手段保存论文。(保密的论文在解密后遵守此规定)

本学位论文属于保密在____年解密后适用本授权书。

本人签名:日期:

导师签名:日期:

第一章绪论 1

第一章绪论

1.1 研究背景

随着计算机技术和网络通信技术的高速发展,软件已经广泛的应用于各行各业以及人们的日常生活当中,发挥着巨大作用。但是由于软件本身的一些缺陷或者弱点,使得运行时出现错误或者异常,从而直接或者间接的造成一定的经济损失,甚至是人员伤亡。特别是在航空航天、国防军事、金融、电信等领域,软件一旦出现故障,损失巨大。

Java语言由于其跨平台性以及对网络和分布式应用的良好支持,使得它在很多领域特别是互联网、金融、电信等领域有着广泛的应用。但是由于该语言本身的特点,Java程序也会出现很多缺陷。其中包括C/C++程序的常见错误,如空指针的脱引用、数组访问越界。还包括一些其它错误,如竞争条件、死锁。这些缺陷对Java程序软件的质量和安全性造成影响。

如果在软件投入使用之前,利用一定的方法和手段对程序中的漏洞进行检测,就可以排除一些在软件运行阶段可能出现的错误,从而提高软件的质量和安全性。本文所在课题旨在研究一个通过静态程序分析[1]从Java字节码文件中检测出潜在安全漏洞的工具。本文论述的重点是,如何通过对Java字节码文件的分析,生成组织结构合理的符号表和抽象语法树,为后端程序分析模块提供完整的程序信息。

1.1.1程序分析和安全检查

软件安全问题主要分为两种。一种是软件本身的缺陷引起的运行时错误或者异常,另一种是软件由于受到外部攻击而引起的运行时错误或者异常,本文主要关注的是前者。如何在软件投入使用之前,尽可能的发现软件中所隐藏的安全漏洞[19]一直是计算机技术领域的研究热点。目前主要有两种方法使用的较为广泛。

(1) 动态分析[22]

动态分析指通过输入特定的测试用例并运行程序来发现程序问题。这种方法能够发现较多的程序问题,如软件功能错误。但是,动态分析与输入的测试用例有很大关系,如果测试用例选择的不好会漏掉很多程序问题。而且很多软件问题有不可再现性,如并发错误。这就使得用动态分析发现某些程序错误的难度大为增加。

(2) 静态分析[14,20,21]

Java程序安全检查工具前端的设计与实现

2

静态分析是通过对软件代码或者相关内容进行分析而发现程序错误的方法。它不用运行程序,并且减少了程序员通过阅读代码进行错误发现的负担,提高了发现错误的效率和速度,节省了软件质量控制成本。并且对程序进行静态分析,能够检查出很多隐蔽且难以通过动态检查发现的错误,如并发程序错误。

本文工作所属的课题围绕程序的静态分析展开,即在不运行程序的前提下,通过分析Java字节码文件指出程序中潜在的漏洞。

1.1.2相关工作

随着Java程序安全检查需求的增加,促进了一些开源和商业检查工具的研究。目前比较成熟的工具有以下几种,它们的实现技术和侧重点各有不同。

(1) JLint[2]

该工具分析Java字节码,执行语法检查和数据流分析。同时,Jlint还具有跨过程、跨文件的分析功能,通过构建锁向图(lock graph)和确保该图中不包含环路来检查死锁。不过它的可扩展性比较差。

(2) PMD[3]

PMD在源代码上执行语法检查。但是,PMD检查的很多错误都与代码风格相关。如try语句后面使用了空catch块,这样可能导致捕获的程序异常被忽略。PMD 有很好的扩展性,除了本身包含一些漏洞检查功能之外,还可以通过用户编写一些检查规则来扩展功能。

(3) FindBugs[4]

FindBugs是利用Java程序漏洞模式进行错误匹配的工具。它的主要技术之一就是在语法形式上匹配程序漏洞模式,进而发现可疑程序代码段。例如,FindBugs 检测到多线程Java程序使用wait()方法时,则检查该方法是否在一个循环体里面。不同于PMD,该工具是进行字节码文件分析的。

(4) Bandera[5]

该工具是一种基于模型检查(model checking)[29]的验证工具。要完成检查,程序员必须参照说明在Java源代码中添加注释。另外Bandera不能分析Java标准库文件,这将极大地限制它的使用范围。

(5) ESC/Java[6]

该工具是一种基于理论证明、Java源代码属性的形式化验证的静态检查工具。要完成检查,程序员必须参照说明在Java源代码中添加前置条件(precondition),后置条件(postcondition)和循环体中的不变量(invariant)等形式的注释。ESC/Java使用一个理论推导组件进行程序的正确性验证。不过ESC/Java在没有添加任何注释的情况下也可以进行一些检查。如解空引用和数组越界访问。

第一章绪论 3

以上工具主要分为两种,一种是基于源代码进行分析,如PMD。基于源代码分析的工具的实现技术主要使用编译器技术,通过词法、语法分析收集静态程序信息,缺点是无法收集到完整的源程序文件,而使得漏洞检查的准确度受到影响;另一种是基于字节码进行分析,如Jlint。基于Java字节码分析的工具主要是使用字节码分析工具对静态程序信息进行收集,它最大的特点是能够收集完整的程序信息,所以可以进行更为深入和准确的安全检查。但是目前的此类检查器在安全检查规则扩展这块有缺失,本文所在的课题旨在研究一个能够收集完整程序信息,支持检查规则扩展的程序安全检查器。

1.2 软件安全检查工具概述

本论文来源于一个实际科研项目,旨在研究开发一个通过静态分析程序代码发现潜在软件安全错误的工具软件。该软件模块包括前端和后端两部分。前端负责解析Java字节码,生成符号表和抽象语法树。后端主要负责在前端生成的符号表和抽象语法树基础之上,运用数据流分析[7]等程序分析技术进行程序错误发现并报告错误。

其整体框架图如图1.1所示,检查器前端由以下四部分组成。

1.符号表解析器:该模块主要负责解析Java字节码获取程序符号信息。程

序符号信息包括名字信息、作用域信息、类型信息、以及各类符号之间

的引用关系。

2.抽象语法树解析器:该模块主要负责解析Java字节码获取程序的抽象语

法树信息。程序的抽象语法树信息包括表达式语法树和语句语法树。

3.控制流图分析器:该模块主要通过分析抽象语法树,生成带有抽象语法

树信息的控制流图供后端分析使用。

4.函数依赖分析器:该模块主要通过分析控制流图得到函数调用图,然后

根据函数调用图生成函数拓扑排序供后端使用。

后端在前端提供的信息的基础上,通过自上而下的数据流分析进行程序安全检查。后端主要包括以下两个部分。

1.数据流分析器:基于函数拓扑排序序列,自上而下依次扫描控制流图,通

过数据流分析计算数据流信息;

2.安全分析器:基于函数拓扑排序序列,自上而下依次扫描控制流图,利用

数据流分析器提供的数据流信息检查是否出现违反安全规则的现象,如果

是,则报告安全漏洞。

本项目的特点主要体现在两个方面。首先,该工具的分析对象是字节码文件。这样就可以避免分析源文件时存在的部分源文件无法找到的问题。其次,该工具

Java程序安全检查工具前端的设计与实现

4

可以对安全检查规则进行扩展。本工具可以通过定义外部安全规则来扩展安全检查器的功能,有较强的可扩展性。

图1.1 安全检查工具框架

1.3 本文工作及内容组织

本文的主要工作是使用ASM(一种字节码操作工具的名称)对Java字节码进行解析生成完整的程序中间表示,为后端提供数据流分析和安全分析的基础。这里

第一章绪论 5

的程序中间表示是指符号表和抽象语法树。

论文内容组织如下。

第一章说明常见的几种Java程序安全检查器及它们各自的技术特点,并简述本文所在项目的框架及特点。

第二章讨论将Java字节码作为分析对象的原因;研究Java字节码的文件结构,字节码中符号的名字规则,以及字节码指令的执行模型;最后讨论字节码分析器ASM的优点以及对前端构造的支持。

第三章给出符号表的总体结构,详细讨论类型、函数符号的设计。最后论述如何进行符号信息收集,以及符号表的生成、查找和使用方法。

第四章给出抽象语法树的总体结构,详细讨论表达式树,语句树的设计。最后论述如何从字节码指令中抽取出抽象语法树信息。

第五章总结本文已完成的工作,列举不足之处和未完成的内容,并提出下一步工作和目标。

第二章ASM与Java安全检查器前端7 第二章ASM与Java安全检查器前端

Java检查器前端是安全检查工具的重要组成部分,它负责分析Java字节码文件,从中提取出符号表、抽象语法树并存储于相应的数据结构中。符号表和抽象语法树的建立是整个前端的基础,它影响着控制流图和函数拓扑排序的信息的收集,进而影响着后端安全分析的效果。所以,前端的设计至关重要。

依据Java检查器前端的输入文件类型,前端主要有两种设计方案。

(1)基于源代码分析的前端设计

该方法使用词法分析、语法分析、语法制导翻译[13,17,18]等编译器技术,通过对源程序的词法、语法分析,并使用语法制导翻译技术在语法分析的过程中添加语义动作,建立符号表和抽象语法树。但是,该方案用于Java前端设计有以下不足。

1)源程序文件难以收集完整

在Java源程序文件中,所引用的类型声明可能存在于源文件中,也可能存在于字节码文件中。特别是Java程序库和商用类库,很难获得源程序文件。所以,基于Java源代码分析的缺点之一就是源程序文件很难收集完整。

2)符号解析复杂

在分析源文件的情况下,很多符号解析工作都有着比较复杂的算法。如函数重载解析算法[27,28],该算法用于在符号解析阶段进行函数引用与声明链接,确定实际引用的函数。如果进行源代码分析,大量的符号解析工作需要完成,这样会影响前端的运行效率。

(2)基于字节码分析的前端设计

该方法将Java字节码文件作为分析对象,从字节码文件中提取所需要的程序信息。基于字节码分析有以下优点。

1)字节码文件完整

基于源程序分析存在部分源文件无法获得的情况,如使用Java平台提供的类库或者其它商用的第三方类库。而基于字节码分析就比较好的解决了这一问题。因为无论是类库文件或者程序员自己编写的Java源代码,最终都以字节码文件的形式存在。这样就可以将所有的字节码文件使用统一的方式进行处理,减小了前端设计的复杂性。

2)避免了符号解析工作

字节码文件中的符号有着严格的命名规范,除了局部变量以外都使用全限定名。符号的全限定名指明了实际引用的类型、方法或域的具体声明位置。例如,

Java程序安全检查工具前端的设计与实现

8

在字节码文件中,被调函数的名字信息包括全限定名、参数类型列表和返回值类型。通过这些信息足以定位所引用的具体函数,不需要进行函数重载解析。

本文采用第二种方案,构造基于字节码分析的Java检查器前端。

2.1 Java字节码概述

Java字节码文件是Java源程序文件经编译器编译生成的目标代码,由于文件后缀名是“class”,所以又名类文件。每个字节码文件代表了一个完整的类型或者接口定义。字节码文件有着严格的格式定义,用以确保所有字节码文件能够在任何一个Java虚拟机上正确执行。虽然Java源文件和字节码文件紧密相关,但是这两者有很多不同之处,主要有以下几点。

(1)源文件中可以包含一个或多个类,而编译后的字节码文件只能包含一个类;

(2)编译后的字节码文件不包含注释,但包含了源文件名、行号、类名、基类、

继承接口、域、方法等程序信息;

(3)字节码文件中无package或是import语句对应的结构,文件中所有的类型

名都是全限定名。

为了构造基于字节码的检查器前端,必须对字节码文件的结构、字节码文件中符号的名字规则、字节码指令的语义以及执行模型有着清楚的了解。这些内容将在后续几节中详细讨论。

2.1.1Java字节码文件结构

Java字节码文件的总体结构是比较简单的。不同于其它目标代码,字节码文件中保留了完整的程序结构和符号信息[8]。一个类或接口的字节码文件结构如图2.1所示,主要包括以下几个部分。

(1)基类(Super Class)

该部分指向一个字符串常量,这个字符串常量是直接基类的全限定名。

(2)继承接口列表(Interfaces)

该部分是一个指针数组,此数组中存放了类的所有直接继承接口的全限定名的指针。

(3)源文件名(Source file name)

指向表示该字节码文件所来源的Java源文件的名字。

(4)域列表(Fields)

该部分对类或接口中声明的所有域进行了细致的描述。域列表中仅列出了本类或接口中声明的所有域,并不包括从基类和接口继承而来的域。

第二章ASM与Java安全检查器前端9

(5)方法列表(Methods)

该部分对类或接口中声明的所有方法进行了细致的描述,包括方法的名称、参数和返回值的类型、该方法体的字节码指令序列等。方法列表里仅存放了本类或本接口中声明的方法,并不包括从基类和接口继承而来的方法。

图2.1 Java字节码文件结构(*代表0个或多个)

(6)修饰符列表(Modifiers)

指明了类型、域、方法声明的访问修饰符,如public、private、abstract、final 等。

(7)名字(Name)

指向一个表示符号全限定名的字符串常量,这里的符号包括类、接口、域、方法等。

(8)常量池(Constant Pool)

它是一个数组,存放了类中各种字符串常量、类名、方法名和接口名以及对外部类的引用信息等常量。这些常量在常量池中只定义了一次,在字节码其它部分中以字节数组索引的形式被引用。虚拟机必须为每一个被装载的类维护一个常量池,常量池中存储了类型定义中用到的所有类型、域和方法的符号引用,它在Java的动态链接机制中起到了重要的作用。

2.1.2Java字节码符号命名规则

Java源程序经编译器编译以后,其中的符号名字转换为字节码文件中使用的内部名字。字节码文件的内部名字包括全限定名、简单名字、描述符[8]。这三类名字的功能如下。

Java程序安全检查工具前端的设计与实现

10

(1)全限定名(Fully Qualified Name)

在字节码文件中,类、接口、域、方法的名字都是以全限定名的形式出现。通过全限定名可以获取类、接口、域和方法的声明位置。在Java程序执行中,全限定名用于动态链接中符号的定位。全限定名中各个嵌套层次之间用分隔符“/”分开,如类Object的全限定名为“Java/lang/Object”。

(2)简单名字(Simple Name)

在字节码文件中,方法体内声明的所有局部变量使用简单名字。由于局部变量的引用范围限定于它所声明的方法体内,所以不需要使用全限定名进行定位。

(3)描述符(Descriptors)

描述符是用来表示变量、方法类型的字符串。其中,域描述符(Field Descriptor)用来表示变量的类型,方法描述符(method descriptor)用来表示方法的类型。描述符可以用下面的上下文无关文法表示。在该文法的产生式中,非终结符用加粗字体来表示,终结符使用正常字体来表示。每个产生式的左部和右部用冒号分开,候选项用“|”分开。

1)域描述符文法

FieldDescriptor:

FieldType

ComponentType:

FieldType

FieldType:

BaseType | ObjectType | ArrayType

BaseType:

B |

C |

D | F | I | J | S | Z

ObjectType:

L

ArrayType:

[ ComponentType

上述文法开始符号为FieldDescriptor;表示一个类型或者接口的全限定名;右边的分号是终结符;其余终结符的含义如图2.2所示。整型“int”用“I”表示。数组使用“[”和元素类型表示,如二维整型数组“int [] []”用“[ [ I”表示,“Object[]”用“[ LJava/lang/Object;”表示。

2)方法描述符文法

方法描述符包括方法的参数类型和返回值类型,但不包含方法的名字和其参数的名字。其描述文法如下。

MethodDescriptor:

第二章ASM与Java安全检查器前端11

(ParameterDescriptor* ) ReturnDescriptor ParameterDescriptor:

FieldType

ReturnDescriptor:

FieldType | V

上述文法的开始符号为MethodDescriptor;V表示无返回值void;第一个产

生式右部的左右括号均为终结符。

方法描述符用字符串表示,从左括号开始,接着是每个参数的域描述符,跟着是右括号,最后是该方法返回值的域描述符或者V。例如,方法“int getSize( )”的方法描述符为“( ) I”;方法“void main(String[] args)”的描述符为“( [ LJava/lang/String; ) V”;方法“void wait(long timeout, int nanos)”的描述符为

“( JI ) V”。

字节码内部名J a v a类型解释

B b y t e字节

C c h a r U n i c o d e字符

D d o u b l e双精度浮点数

F f l o a t单精度浮点数

I i n t整数

J l o n g长整型

L;r e f e r e n c e类

S s h o r t短整型

Z b o o l e a n布尔类型

[r e f e r e n c e数组

图2.2 Java类型描述符

2.1.3Java程序执行模型与字节码指令

(1)Java程序执行模型

Java字节码在虚拟机上执行,基于栈进行运算。在程序执行过程中,每个线程都有自己的执行栈(execution stack)。而执行栈由帧(frame)组成,每个帧对应于一次方法调用。当方法被调用时,一个新帧就被压入当前线程的执行栈;当方法返回时,该帧将从执行栈中弹出,然后在调用方法中继续执行。

帧由局部变量区(local variables part)和操作数栈(operand stack part)两部分组成。局部变量区是一个连续存储区域,包含了该方法体中声明的所有局部变量,虚拟机通过局部变量区的索引进行随机访问。操作数栈是用于存放字节码指令操作数的栈,只能按照后进先出的方式访问。线程的执行栈和帧内部的的操作数栈是两个不同的概念,执行栈中的每一个帧包含一个操作数栈,如图2.3所示。

Java程序安全检查工具前端的设计与实现

12

图2.3 Java执行栈示例图

局部变量区和操作数栈的大小取决于方法的源代码,它在编译时计算出来,并且随着已编译的字节码指令存储于字节码文件中。

帧在创建时,操作数栈被初始化为一个空栈。局部变量区中的方法实参首先被初始化,余下的局部变量暂不进行初始化。

(2)字节码指令集

字节码指令由一个指令码(opcode)和固定数目的指令参数表(arguments)组成。

指令码是一个无符号字节值。例如,字节码指令“NOP”的字节值为0,对应的指令语义是无操作。

指令参数表是一组定义具体指令行为的静态值,位于字节码指令之后。例如,“GOTO label”的指令参数表是“label”,它是一个标签,表示下一个将被执行的指令地址。指令参数表和指令操作数是不同的两个概念,指令参数表的值编译时可以确定,而操作数的值来自于操作数栈,在运行时确定。

根据指令的执行特点,可以将字节码指令分为两大类,如下所示。

1)用于在局部变量区和操作数栈之间传值的指令集合

例如,字节码指令ILOAD、LLOAD、DLOAD和ALOAD的语义为,读一个局部变量并把它的值压入到操作数栈中,这类指令把局部变量的索引作为参数。ILOAD用于载入一个boolean、byte、char、short或int类型的值。ALOAD用于载入所有非基本类型引用,比如对象或数组引用。对称地,ISTORE、LSTORE、DSTORE和ASTORE指令从操作数栈中弹出一个值并将它写回一个通过索引指定的局部变量。

2)用于操作数栈计算的指令集合

该类指令从栈顶弹出若干值,并计算出基于这些值的结果,最后将结果压回栈中。由于指令种类比较多,可以将其细分为以下十类指令。

[1]栈(Stack)

该类指令作用于操作数栈。例如,字节码指令POP弹出栈顶的值;指令DUP 压入一个栈顶值的拷贝;指令SW AP从栈顶弹出两个值,将它们以相反的顺序压

第二章ASM与Java安全检查器前端13

入等。

[2]常量(Constants)。

该类指令向操作数栈中压入一个常量值。指令ACONST_NULL压入一个空引用null;指令ICONST_0压入一个整型值0;指令FCONST_0压入float浮点型值0f;指令DCONST_0压入double浮点型值0d,“BIPUSH b”压入Byte型值b,“SIPUSH s”压入short型值s,指令“LDC cst”压入int,float,long ,double,String等类型的常量cst。

[3]算术和逻辑运算(Arithmetic and logic)

该类指令从操作数栈顶弹出若干数值,进行算术逻辑运算后将结果压入到栈中。对应于加、减、乘、除、取余数的字节码指令为xADD、xSUB、xDIV、xREM。类似的还有对应于操作符<<,>>,>>>,&,^的字节码指令。

[4]类型转换(Casts)

这类指令从栈中弹出一个值,将它转换为另外一种类型,并将结果压回栈顶。字节码指令I2F,表示将int类型的数值转换为float类型的数值。字节码指令“CHECKCAST t”,表示将栈顶引用的类型转化为目标类型t。

[5]对象(Objects)

这类指令用来创建对象、锁对象和检测对象的类型等。例如,字节码指令“NEW type”压入一个类型为type的新对象引用到栈中。

[6]域(Fields)

这类指令用于读或者写一个域的值。字节码指令“GETFIELD owner name desc”从栈顶弹出一个类型名字为owner的对象,并将该对象中名字为name的域的值压入栈中,域的类型名字为desc。相反,字节码指令“PUTFIELD owner name desc”弹出一个值和一个对象,然后将这个值存入对象中的名字为name的域中。GETSTA TIC和PUTSTA TIC是针对静态域的字节码指令。

[7]方法(Mehtods)

该类指令用于调用方法或者构造函数。指令执行的具体过程为,先弹出和方法形参个数相同的值、目标实体的值(this)作为被调函数的实参,然后调用方法并将方法计算的结果压入栈顶。字节码指令“INVOKEVIRTUAL owner name desc”调用在名字为owner的类型中声明的名字为name的方法,该方法的方法描述符为desc。指令INVOKESTA TIC被用于静态方法。指令INVOKESPECIAL用于构造方法,指令INVOKEINTERFACE用于在接口中声明的方法。

[8]数组(Arrays)

该类指令用于读或者写数组中的值。字节码指令IALOAD表示从当前栈顶弹出索引值和数组引用,压入数组在该索引处的整型值。相反,IASTORE指令弹出一个整型值,索引和数组引用,然后将该整型值写入数组的索引位置。

Java程序安全检查工具前端的设计与实现

14

[9]跳转(Jumps)

跳转类指令分为无条件跳转和条件跳转两种。无条件跳转指令“goto lable”表示无条件跳转到标签lable指向的字节码指令。条件跳转指令对应于源程序中的if, for, do while, break和continue等程序语句。例如,字节码指令“IFEQ label”表示从栈顶弹出一个整型值,判断该整型值是否等于零。如果等于零,则跳转到label 指定的指令;否则继续执行。

[10]返回(Return)

字节码指令RETURN表示终止方法的执行。ARETURN表示终止方法的执行,并且将当前栈顶的对象引用返回。

2.2 ASM对前端构造的支持

由于源代码符号解析复杂以及源程序文件难以收集完整,本文采用Java字节码文件作为分析对象,即通过解析Java字节码文件来实现符号表和抽象语法树的创建。

从字节码文件中提取程序信息有多种方法和手段,最常用的是使用已有的字节码分析工具对字节码进行解析。这种方法避免了直接对字节码文件进行操作,减小了字节码分析的复杂度。

目前针对Java字节码的分析工具很多,以下列举了常见的几种分析工具。

JOIE[9](Java Object Instrumentation Environment)是第一个针对Java字节码的转化工具,JOIE用对象表示字节码文件,但是现在已经很少使用。

BCEL[10](Byte Code Engineering Library)是目前使用较为广泛的一种字节码操作框架。针对字节码文件结构中的各种结点和指令,BCEL构建了270多个类来表示字节码文件的结构,每个指令对应一个对象。它能够在Java字节码指令层次上直接进行操作。不过,BCEL框架类型繁多、使用起来比较复杂。

ASM[11]是一种轻量级的Java字节码的处理框架,它的名字本身没有特殊含义,只是对C语言中的关键字“__asm__”的引用。相比于其它的同类工具,它更好的隐藏了字节码的复杂性,并且提供了更好的性能,其主要的优势如下。

(1)简单、规范和模块化的应用程序接口(API)使用起来很方便;

(2)文档齐全,并且提供与Eclipse结合的插件,在实际开发应用中可方便的

查看源文件对应的字节码文件;

(3)相比同类工具,ASM设计的较小,在运行时速度也较快,而且具有良好的

健壮性;

(4)ASM是开源软件,便于使用和扩展。

所以,本项目选择ASM进行字节码的解析工作。

第二章ASM与Java安全检查器前端15 2.2.1ASM简介

(1) ASM的工作原理

ASM的主要目标是分析和转化字节码文件。它使用访问者模式(Visitor pattern)实现。主要组件为字节码文件解析器(ClassReader)和字节码访问接口(ClassVisitor)。其中,字节码文件解析器主要负责解析字节码文件,并根据当前分析的字节码元素类型调用具体的访问方法。字节码访问接口规定了进行字节码文件解析时所调用的访问方法。下面的代码片段是这两个组件的使用示例。

01 ClassReader cr = new ClassReader(“https://www.doczj.com/doc/84127712.html,ng.StringBuilder”);

02 MyClassVisitor cn = new MyClassVisitor();

03 cr.accept(cn, 0);

上述代码的执行过程为。

第一步,生成字节码文件解析器cr,并设置将要分析的字节码文件,该字节码文件用类的全限定名来表示。例如,在上述代码中,字节码文件解析器会根据全限定名https://www.doczj.com/doc/84127712.html,ng.StringBuilder获得其对应的字节码文件。

第二步,生成一个字节码访问对象cn,cn的类型为MyClassVisitor,MyClassVisitor访问类实现了ASM的字节码访问接口。该接口的定义如图2.4所示。可以看出,该接口内部包含了若干个访问方法,这些方法在分析字节码文件时被调用。

第三步,启动字节码解析器的文件解析方法,并在字节码文件的解析过程中调用MyClassVisitor类实现的字节码访问方法。

public interface ClassVisitor {

void visit(int version, int access, String name, String superName, String[] interfaces);

void visitSource(String source, String debug);

void visitOuterClass(String owner, String name, String desc);

void visitAttribute(Attribute attr);

void visitInnerClass(String name, String outerName, String innerName, int access);

AnnotationVisitor visitAnnotation(String desc, boolean visible);

FieldVisitor visitField(int access, String name, String desc, Object value);

MethodVisitor visitMethod(int access, String name, String desc, String[] exceptions);

void visitEnd();

}

图2.4 ClassVisitor接口

ClassVisitor接口中的每个方法对应于类文件中的一个同名元素,如visit方法对应于类或接口的声明,visitField方法对应于类体中域的声明,visitMethod方法

Java程序安全检查工具前端的设计与实现

16

对应于类体中方法的声明。

在解析字节码文件的过程中,字节码访问接口的方法调用次序是固定的,如图2.5所示。

visit visitSource?visitOuterClass?(visitAnnotation |visitAttribute )*

(visitInnerClass |visitField |visitMethod )*

visitEnd

图2.5 ClassVisitor中方法的调用次序

ClassVisitor接口在解析字节码文件的过程中方法的调用次序是。

1)调用方法visit;

2)至多调用一次方法visitSource;

3)至多调用一次方法visitOuterClass;

4)调用任意次数的visitAnnotation或visitAttribute方法;

5)调用任意次数的visitInnerClass或visitField或visitMethod方法;

6)调用visitEnd表示结束访问。

规定上述方法调用次序,与字节码文件的结构和字节码文件中各个组成元素的出现顺序有关,这样做有利于ASM进行字节码文件的解析。

(2) ASM的字节码文件转化功能

ASM的一项重要功能就是将字节码文件转化为对象表示形式。该功能由核心组件ClassNode类实现,ClassNode的定义体如图2.6所示,类体内声明的各个域分别对应于字节码文件的各组成元素。ClassNode类实现了ClassVisitor接口的所有方法,这些方法的功能是提取字节码文件中各个组成元素信息并将之存入到ClassNode对应的域中,即将字节码文件转化为ClassNode类型的对象。每个字节码文件经ASM转换之后都能生成一个对应的ClassNode类型的对象。具体的代码如下。

01 ClassReader cr = new ClassReader(“https://www.doczj.com/doc/84127712.html,ng.StringBuilder”);

02 ClassNode cn = new ClassNode();

03 cr.accept(cn, 0);

上述代码的执行过程为。

第一步,生成字节码文件解析器cr,并设定将要分析的字节码文件。

第二步,生成ClassNode类型的对象cn,该对象用于存储待分析字节码文件的信息。

第三步,启动字节码解析器的文件解析方法。在该解析过程中,ClassNode的方法按照图2.5所示的顺序被调用,每个方法将其对应的字节码文件组成元素存入对象cn中。这样,就将字节码文件转化为对象形式。

第二章ASM与Java安全检查器前端17

2.2.2ASM对符号表生成的支持

符号表解析器的主要任务就是利用ASM的字节码文件分析和转化功能,将待分析的字节码文件转化为对象形式,然后从这些对象中获取符号信息,包括类型、变量、函数、包等。并将这些符号信息存入自定义的符号表中。

ASM的转化字节码文件功能主要是由ClassNode类来实现的,该类继承了ClassVisitor接口。ClassNode类的定义如图2.6所示。

public class ClassNode implements ClassVisitor {

public int version;

public int access; //类访问限定

public String name; //类名字

public String superName; //直接基类名字

public List interfaces; //继承接口名字列表

public String sourceFile; //源文件名字

public List innerClasses; //内部类列表

public List fields; //域列表

public List methods; //方法列表

}

图2.6 ClassNode类的主要结构

根据其定义,从ClassNode中可以获得当前类型的名字、继承的基类和接口名字、类型声明所在的源文件、域列表、方法列表等。域列表fields保存了被分析类型中声明的所有域,该列表每个结点的类型为FieldNode,该类型中包含了域的名字、类型、访问限定等信息。方法列表methods保存了被分析类型中声明的所有方法,该列表每个结点的类型为MethodNode,该类型中包含了方法名字、方法描述符、异常列表、局部变量列表、以及方法体的字节码指令链表等,MethodNode类定义如图2.7所示。这些都是生成符号表的信息来源。

2.2.3ASM对抽象语法树生成的支持

抽象语法树解析器通过分析字节码指令序列,模拟字节码指令在操作数栈上的执行,确定抽象语法树和符号之间的引用关系,进而恢复出程序的的抽象语法树结构。由于抽象语法树解析器的分析对象为字节码指令序列,这就需要字节码分析工具在这部分有较为强大的支持。ASM中MethodNode类的instructions成员保存了当前方法体对应的字节码指令序列,可以作为抽象语法树的分析对象。

Java程序设计实例教程考试题

Java程序设计练习题 一、选择题 1、为使Java程序独立于平台,Java虚拟机把字节码与各个操作系统及硬件( A ) A)分开B)结合 C)联系D)融合 2、Java语言与C++语言相比,最突出的特点是( C ) A)面向对象B)高性能 C)跨平台D)有类库 3、下列Java源程序结构中前三种语句的次序,正确的是(D) A)import,package,public class B)import必为首,其他不限 C)public class,package,import D),import,public class 4、在JDK目录中,Java程序运行环境的根目录是( A ) A)bin B)demo C)lib D)jre 5、下列运算符中属于关系运算符的是(A ) A)== B).= C)+= D)-= 6、下列布尔变量定义中,正确并且规范的是( B ) A)BOOLEAN canceled=false; B)boolean canceled=false; C)boolean CANCELED=false; D)boolean canceled=FALSE; 7、下列关键字中可以表示常量的是( A ) A)final B)default C)private D)transient 8、下列运算符中,优先级最高的是( A ) A)++ B)+ C)* D)> 9、Java中的基本数据类型int在不同的操作系统平台的字长是( B ) A)不同的B)32位 C)64位D)16位

10、给一个short类型变量赋值的范围是( C ) A)-128 至 +127 B)-2147483648至 +2147483647 C)-32768至 +32767 D)-1000至 +1000 11、下列运算中属于跳转语句的是( D ) A)try B)catch C)finally D)break 12、switch语句中表达式(expression)的值不允许用的类型是( C ) A)byte B)int C)boolean D)char 13、下列语句中,可以作为无限循环语句的是( A ) A)for(;;) {} B)for(int i=0; i<10000;i++) {} C)while(false) {} D)do {} while(false) 14、下列语句中执行跳转功能的语句是( C ) A)for语句B)while语句 C)continue语句D)switch语句 15、下列表达式中,类型可以作为int型的是( C ) A)“abc”+”efg”B)“abc”+’efg’ C)‘a’+’b’D)3+”4” 17、数组中各个元素的数据类型是( A ) A)相同的B)不同的 C)部分相同的D)任意的 18、在Java语言中,被成为内存分配的运算符是( A ) A)new B)instance of C)[] D)() 19、接口中,除了抽象方法之外,还可以含有( B ) A)变量B)常量 C)成员方法D)构造方法 20、下列能表示字符串s1长度的是( A ) A)s1.length()B)s1.length C)s1.size D)s1.size() 21、StringBuffer类字符串对象的长度是( C ) A)固定B)必须小于16个字符 C)可变D)必须大于16个字符 22、构造方法名必须与______相同,它没有返回值,用户不能直接调用它,只能通过new调用。( A ) A)类名B)对象名 C)包名D)变量名 23、子类继承了父类的方法和状态,在子类中可以进行的操作是( D ) A)更换父类方法B)减少父类方法 C)减少父类变量D)添加方法 24、String、StingBuffer都是______类,都不能被继承。( C )

04747java语言程序设计(一)20120年01月试卷

全国2012年1月高等教育自学考试 Java语言程序设计(一)试题 课程代码:04747 一、单项选择题(本大题共10小题,每小题1分,共l0分) 在每小题列出的四个备选项中只有一个是符合题目要求的,请将其代码填写在题后的括号内。错选、多选或未选均无分。 1.下面供选字符序列中,不属于 ...Java语言关键字的是( ) A.inner B.throw C.false D.throws 2.表达式“-1>>>1”的十进制值是( ) A.-2 B.231-1 C.-(231-1) D.232-1 3.Java语言中,在类定义时用final关键字修饰,是指这个类( ) A.子类必须实现父类未实现的方法 B.没有具体实现代码 C.必须要有实例 D.不能被继承 4.表达式"java程序设计".1ength()的值是( ) A. 0 B.12 C. 8 D.13 5.以下关于BorderLayout布局的叙述中,不正确 ...的是( ) A.把容器内的空间划分成5个区域 B.加入组件应该指明要放入的区域 C.是框架窗口的默认布局 D.一个位置可直接放多个组件 6.利用文件对话框打开或保存文件,在打开文件对话框之前,可用FileFilter类设置筛选条件,其所用的两个方法是( ) A.accept()和getSelectedFile() B.accept()和getDescription() C.accept()和setDescription() D.setDescription()和getDescription() 7.设已经有Graphics2D对象g2d,RoundRectangle2D对象rRect,绘制对象rRect的代码是( ) A.g2d.draw(rRect) B.g2d.drawRoundRect(rRect) C.rRect.draw() D.rRect.drawRoundRect() 8.以下关于线程互斥和同步的叙述中,正确的是( ) A.临界段是线程互斥使用资源的程序段 B.临界段能使线程使用其它线程的资源 浙04747# Java语言程序设计(一)试卷第1页(共12页)

JAVA程序设计期末考试题(多套含答案)

《JA V A程序设计》期末考试试题(五) 一、单选题 1、当某一线程正处于休眠状态,而另一个线程用Thread 类中的interrupt() 方法中断它时,抛出的异常类型是()。 A) IOException B) RuntimeException C) InterruptedException D) ClassNotFoundException 2、下面的程序段的功能是( )。 File file1=new File("d:\\xxx\\yyy\\zzz"); file1.mkdirs(); A)在当前目录下生成子目录:\xxx\yyy\zzz B)生成目录:e:\xxx\yyy\zzz C)在当前目录下生成文件xxx.yyy.zzz D)以上说法都不对 3、应用程序的main方法中有以下语句,则输出的结果是( )。 String s = "xxxxxxxxxxxxxxx#123#456#zzzzz"; int n = s.indexOf("#"); int k = s.indexOf("#", n+1); String s2 = s.substring(n+1, k); System.out.println(s2); A) 123456 B) 123 C) xxxxxxxxxxxxxxx D) zzzzz 4、关于下面的程序Test.java说法正确的是( )。 public class Test { String x="1"; int y; public static void main(String args[]) { int z=2; System.out.println(x+y+z); } } A)3 B)102 C) 12 D)程序有编译错误 5、应用程序的main方法中有以下语句,则输出的结果是( )。

Java语言程序设计基础教程习题解答

《Java语言程序设计基础教程》练习思考题参考答案

第1章 Java程序设计概述 练习思考题 1、 Java运行平台包括三个版本,请选择正确的三项:() A. J2EE B. J2ME C. J2SE D. J2E 解答:A,B,C 2、 Java JDK中反编译工具是:() A. javac B. java C. jdb D. javap 解答:D 3、 public static void main方法的参数描述是:() A. String args[] B. String[] args C. Strings args[] D. String args 解答:A,B 4、在Java中,关于CLASSPATH环境变量的说法不正确的是:() A. CLASSPATH一旦设置之后不可修改,但可以将目录添加到该环境变量中。 B. 编译器用它来搜索各自的类文件。 C. CLASSPATH是一个目录列表。 D. 解释器用它来搜索各自的类文件。 解答:A 5、编译Java Application源文件将产生相应的字节码文件,扩展名为() A. .java B. .class C. .html D. .exe 解答:B 6、开发与运行Java程序需要经过的三个主要步骤为____________、____________和____________。 7、如果一个Java Applet源程序文件只定义有一个类,该类的类名为MyApplet,则类MyApplet必须是______类的子类并且存储该源程序文件的文件名为______。 8、如果一个Java Applet程序文件中定义有3个类,则使用Sun公司的JDK编译器编译该源程序文件将产生______个文件名与类名相同而扩展名为______的字节码文件。 9、开发与运行Java程序需要经过哪些主要步骤和过程? 10、Java程序是由什么组成的?一个程序中必须要有public类吗?Java源文件的命名规则是怎么样的? 11、编写一个简单的Java应用程序,该程序在命令行窗口输出两行文字:“你好,很高兴学习Java”和“We are students”。

Java语言程序设计课后习题答案

Java语言程序设计(郑莉) 第二章习题答案 1.什么是对象、类,它们之间的联系 答:1)对象是包含现实世界物体特征的抽象实体,它反映系统为之保存信息和与它交互的能力。对象是一些属性及服务的封装体,在程序设计领域,可以用“对象=数据+作用于这些数据上的操作”来表示。现实生活中对象是指客观世界的实体;在程序中对象是指一组变量和相关方法的集合。 2)类是既有相同操作功能和相同的数据格式的对象的集合与抽象!3)两者的关系:对象是类的具体实例.。 2.什么是面向对象的程序设计方法它有那些基本特征 答:面向对象程序设计从所处理的数据入手,以数据为中心而不是以服务为中心来描述系统。它把编程问题视为一个数据集合,数据相对于功能而言,具有更强的稳定性。 它的特征:抽象,封装,继承,多态。 3(无用) 4.请解释类属性、实例属性及其区别。 答:实例属性,由一个个的实例用来存储所有实例都需要的属性信息,不同实例的属性值可能会不同。 5.请解释类方法、实例属性及其区别。 答:实例方法表示特定对象的行为,在声明时前面不加static修饰符,在使用时需要发送给一个类实例。 类方法也称为静态方法,在方法声明时前面需加static修饰符,类方法表示具体实例中类对象的共有行为。 区别:实例方法可以直接访问实例变量,调用实例方法,实例方法可以直接访问类变量,调用类方法;类方法可以直接调用类变量和类方法,类方法不能直接调用实例变量和实例方法; 6.类的访问控制符有哪几种具体含义及其区别。 答:类的访问控制符只有public(公共类)及无修饰符(默认类)两种。 区别:当使用public修饰符时表示所有其他的类都可以使用此类;当没有修饰符时,则只有与此类处于同一包中的其他类可以使用类。 7类成员的访问控制符有哪几种他们对类成员分别有哪些访问限制的作用 答:类成员的访问控制符有 public,private,protecte及无修饰符. public(公有的):用public修饰的成分表示公有的,也就是它可以被其他任何对象访问(前提是对累成员所在的类访问有访问权限). Private(保护的):类中限定为private的成员只能被这个类本身 访问,在类外不可见。 proteced(保护的)用该关键字修饰的成分是受保护的,只可以被同一类及其子类的实例对象访问。 无修饰符(默认的):public,private,protected这个三个限定符不是必须写的。如果不写,则表明是“friendly”,相应的成分可以被所在保重的各类访问。 8简述构造方法的特点答:构造方法主要有以下特点: (1)构造方法的方法名与类名相同; (2)构造方法没有返回类型(修饰符void也不能有);(3)构造方法通常被声明为公有的(public); (4)构造方法可以有任意多个参数; (5)构造方法的主要作用是完成对象的初始化工作; (6)构造方法不能在程序中显式的调用; (7)在生成一个对象时,系统会自动调用该类的构造方法为新生成的对象初始化。 9如果在类声明中声明了构造方法,系统是否还提供默认的构造方法 答: 用户在进行类声明时,如果没有声明任何构造方法,系统会赋给此类一个默认(无参)的构造方法。但是,只要用户声明了构造方法,即使没有声明无参的构造方法,系统也不会再赋默认的构造方法。 10:声明Patient类表示在门诊室中的病人。此类对象应包括name(astring)\sex(achar)、age(an integer)、weight(a float0、allergies(a boolean). 声明存取及修改方法。在一个单独的累中,声明测试方法,并生成两个patient的例子: Atient april=new Patient(); (“zhangli”) (‘f’);; (330; ; (true); 那么:”+()); ”+()); ”+()); (“weught: ”+());\ ”+()); 声明并测试toString()方法显示一个病人的aga、sex、name及allergies属性。 答: public class Patient { private String name; private char sex; private int age; private float weight; private boolean allergies; public void setname(String a) { name=a; } public void setsex(char b) { sex=b; }

Java语言程序设计二级考试模拟试卷

Java语言程序设计二级考试模拟试卷一 (考试时间90分钟,满分100分) 一、选择题(1~20题每题2分,20~30题每题3分,计70分) 在下列各题的A、B、C、D、四个选项中,只有一个选项是确定的,请将正确的选项涂写在答题卡相应位置上,答在试卷上不得分。 1、下列叙述中正确的是()。 A、线性表是线性结构 B、栈和队列是非线性结构 C、线性链表是非线性结构 D、二叉树是线性结构 2、下列关于队列的叙述中正确的是()。 A、在队列中只能插入数据 B、在队列中只能删除数据 C、队列是先进先出的线性表 D、队列是先进后出的线性表 3、设有下列二叉树: 对此二叉树前遍历的结果是()。 A、ABCDEF B、DBEAFC C、ABDECF D、DEBFCA 4、设树T的度为4,其中度为1、2、3、4的结点个数分别是4,2,1,1。则T中的叶子结点数是()。 A、8 B、7 C、6 D、5 5、结构化程序设计主要强调的是()。 A、程序的规模 B、程序的易读性 C、程序的执行效率 D、程序的可移植性 6、下面对对象概念描述错误的是()。 A、任何对象都必须有继承性 B、对象是属性和方法的封装体 C、对象间的通讯靠消息传递 D、操作是对象的动态属性 7、在软件测试中,以发现各模块内部可能存在的各种错误为目的的测试是()。 A、集成测试 B、单元测试 C、黑盒测试 D、白盒测试 8、软件需求分析阶段的工作,可以分为四个方面,需求获取、需求分析、编写需求规格说明书以及()。 A、阶段性报告 B、需求评审 C、总结 D、信息隐藏 9、在关系数据库中,用来表示实体之间联系的是()。 A、树结构 B、网结构 C、线性表 D、二维表 10、在关系数据库中,当数据的存储结构改变时,其逻辑结构可以不变,因次,基于逻辑结构的应用程

java程序设计基础(含参考答案)

“Java程序设计基础”课程习题 一、填空 1.Java程序分两类___Applet___和application,Java Application 类型的程序,程序从 ___main方法___开始执行。 2.定义一个Java类时,通过关键字__extends____指明该类的父类。一个类可以有___1___ 个父类。 3.用public修饰的类称为_公有类或公用类__。用public修饰的类成员称为公有成员。被 说明为public的内容可以被__所有其他类___ 使用。如果public类文件与使用它的类文件不在同一目录中,需要通过__import____语句引入。 4.用___private___ 修饰的类成员称为私有成员。私有成员只能在__本类__ 中使用。 5.如果子类定义的成员变量与父类的成员变量同名,称为___方法覆盖___ ,要表明使用 子类的成员变量,可以在成员变量前加上关键字__super___ 。 6.____Object__ 类是Java类库中所有类的父类。 7.Java字符使用__16位的字符集,该字符集成为__Unicode____ 。 8.当子类中定义的方法与父类方法同名时,称子类方法___覆盖___ 父类方法,子类默认 使用自己的方法。使用父类的同名方法,必须用关键字__super__ 说明。 9.Java源程序文件名的后缀是___.java___,Java字节码文件名的后缀是_.class_____。 10.Java类名的第一个字母通常要求___大写___。 11.Java程序由____类__组成,每个程序有一个主类,Java程序文件名应与____主__类的 名称相同。 12.Java__Application_类型的程序需要main()方法,程序从__main____开始执行。 13.布尔型数据类型的关键字是_boolean__ ,占用位数是___1位___ ,有__true__ 和_false_ 两种值。整型数可以采用_十_ 、__八_ 和__十六_三种进制表示。 14.八进制整数以数字__0_开头。十六进制整数以_0x或0X_ 开头。 15.int整型数占用__32位内存。long整型数占用__64 位内存。 16.127L表示__长整型____ 常量。 17.根据占用内存长度将浮点常量分为_double_____ 和__float____ 两种。 18.单精度浮点常量占用__32_ 位内存,双精度浮点常量占用__64 位内存。 19.在Java语言中,字符串“ABC\tD\b\n”中包括__7个字符。 20.数学关系44&&x<9____ 。数学关系x>3且x<=10对应 的Java表达式是_x>3&&x<=10。数学关系x>3或x<-10对应的Java表达式是_x>3||x<-10_。 21.逻辑表达式true&&false&&true的结果是_false_ 。 22.__new__ 运算符的作用是根据对象的类型分配内存空间。当对象拥有内存空间时,会 自动调用类中的构造方法为对象_初始化_。 23.省略访问修饰符的类只能被同_一包_中的类使用,称之具有包访问特性。 24.用public修饰的类称为_公共类_。用public修饰的类成员称为公共成员。被说明为public 的内容可以被_所有类_ 使用。如果public类文件与使用它的类文件不在同一目录中,需要通过_import_语句引入。 25.用_private_ 修饰的类成员称为私有成员。私有成员只能在_本类使用。 26.在类中可以定义多个具有相同名称、但参数不同的方法,这种做法称为__方法重载_ 。 27.如果子类定义的成员变量与父类的成员变量同名,要表明使用子类的成员变量,可以在 成员变量前加上关键字__this__。

Java程序设计实用教程_习题解答

习题 1 1.James Gosling 2.需3个步骤: 1)用文本编辑器编写源文件 2)使用Java编译器(javac.exe)编译源文件,得到字节码文件。 3)使用java解释器(java.exe)来解释执行字节码文件。 3.D:\JDK 1) 设置path 对于Windows 2000/2003/XP,右键单击“我的电脑”,在弹出的快捷菜单中选择“属性”,弹出“系统特性”对话框,再单击该对话框中的“高级选项”,然后单击“环境变量”按钮,添加系统环境变量path。如果曾经设置过环境变量path,可单击该变量进行编辑操作,将需要的值d:\jdk\bin加入即可(注意:修改系统环境变量path后要重新打开DOS窗口编译)。或在DOS窗口输入命令行: set path=d:\jdk\bin(注意:用此方法修改环境变量每次打开DOS窗口都需要输入该命令行重新进行设置)。 2) 设置classpath 对于Windows 2000/2003/XP,右键单击“我的电脑”,在弹出的快捷菜单中选择“属性”,弹出“系统特性”对话框,再单击该对话框中的“高级选项”,然后单击“环境变量”按钮,添加系统环境变量classpath。如果曾经设置过环境变量classpath,可单击该变量进行编辑操作,将需要的值d:\jdk\jre\lib\rt.jar;.;加入即可。或在DOS窗口输入命令行: set classpath= d:\jdk\jre\lib\rt.jar;.;。 4.(B)javac 5.Java源文件的扩展名是”.java”,Java字节码的扩展名是”.class” 6.Java应用程序主类的main申明(D)public static void main(String args[])

Java程序设计习题附答案(一)

Java程序设计题库 第一部分绪论 1、下列关于Java语言的特点,描述错误的是(C) A.Java是跨平台的编程语言B.Java支持分布式计算 C.Java是面向过程的编程语言D.Java支持多线程 2、Java语言具有许多优点和特点,下列选项中,哪个反映了Java程序并行机制的特点?(B) A、安全性 B、多线性 C、跨平台 D、可移植 3、Java JDK中调试器的命令是(C)。 A、javac B、java C、jdb D、avah 4、运行jar文件中class文件需要在java命令后面加的参数为(A)。 A、-cp B-g C-d D-verbose 5、下面哪项在java中是不合法的标识符?(C) A、$user B、point C、You&me D、_endline 6、下面关于Java语言说法正确的是(ABCD)。 A、Java语言是面向对象的、解释执行的网络编程语言。 B、Java语言具有可移植性,是与平台无关的编程语言。 C、Java语言可对内存垃圾自动收集。 D、Java语言编写的程序虽然是“一次编译,到处运行”,但必须要有Java的运行环境。 7、在Java程序设计中,程序员创建()文件,然后编译器把它们转化为()文件。( B) A、源, HTML B、源, 字节代码 C、字节代码, 源 D、HTML, 字节代码 8、Java的JVM是指(B)。 A、由Java操作的家用设备(通常是一个漂亮的小烤箱) B、Java字节代码的解释程序 C、Java源代码的编译器 D、运行Java 所需的硬件设备 9、在Java中,关于CLASSPA TH环境变量的说法不正确的是(A)。 A、CLASSPATH一旦设置之后不可修改,但可以将目录添加到该环境变量中。 B、编译器用它来搜索各自的类文件。 C、CLASSPATH是一个目录列表。 D、解释器用它来搜索各自的类文件。 10、一个可以独立运行的Java应用程序(D)。

java程序设计模拟试题四

《Java 程序设计》模拟试题四 一、选择题(每小题2分,共20分) 1. 以下哪个是合法的标识符? ( C ) A. 7star B. else C. my$ D. super 2. 设有对象obj 具有属性a 则访问该属性的方法为( A )。 A. obj.a B. a.obj() C. a.obj D. obj.a() 3. 下列关于关键字this 和super 的说法正确的是( C )。 A. this 是调用父类的方法和变量 B. super 是调用本类中的方法 C. super 是调用父类的方法和变量 D. 没有区别 4. 以下关于重载(overload )的定义哪个正确?( B ) A.在一个类中,定义了多个具有相同名字的方法,但这些方法有不同的输出参数。 B.在一个类中,定义了多个具有相同名字的方法,但这些方法有不同的输入参数。 C.在一个类中,定义了多个具有相同名字的方法,并且这些方法有相同的输入参数。 D.在一个方法体中定义了多行代码。 5. 有如下代码段: int i=2; int j=3; if((i==2)||(j++==3)) i++; if((j==4)||(i++==3)) j++; System.out.printf("i="+i+"j="+j); 该程序运行的结果为: ( C )。 A .i=4,j=4 B.i=3,j=5 C .i=4,j=5 D.以上都不是 6. Java 程序用以下哪个命令可编译源文件? ( D ) A. Java B. appletviewer C. Javadoc D. Javac 7. 以下说法正确的个数为 ( B )。 ①构造方法中this 语句必须放在第一句; ②构造方法中super 语句不一定放在第一句; ③final 修饰的变量只能赋值一次; ④static 修饰的变量在该对象的一个实例中被修改,在另一个实例中也可以取得该变量的新值。 A. 1 B. 2 C. 3 D. 4 8. 下列修饰词,可以用来定义接口中方法的为 ( C )。 A. private B. protected C. public D.以上都不是 9. 关于继承的说法正确的是( B )。 A.子类将继承父类所有的属性和方法。 B.子类将继承父类的非私有属性和方法。 C.子类只继承父类public 方法和属性 D.子类只继承父类的方法,而不继承属性 10. 下列关于Java 程序中数组的使用说法正确的是( A )。 A.数组必须在使用前定义 B.同一个数组中的元素类型必须不同 C.数组是一种特殊的变量不需在使用前声明 D.数组的元素不可以是数组 评分标准:本题为单项选择题,每小题2分,共10道小题,共20分;每小题选对给2分,选错、多选、不选不给分也不扣分。 二、填空题(每空1分,共10分) 1. Java 的特点有: 简单性、可靠性和安全性、面向对象、平台无关和解释执行、分布式、多线 程等 (不少于4条)。 评分标准:只要写出四条即可给1分,不写或少于四条不给分,也不扣分。 2. Java 的注释有以下三种: 单行注释(//)、多行注释(/* */)、文档注释(/** */) 。 评分标准:本题答案不唯一,只要写出3条即可给1分,不写或少于3不给分,也不扣分。备注:不写汉字,只写括号中的符号也算正确,或者汉字和符号的组合也对。 3. 建立文件”file.txt ”的字节输入流的语句是 FileInputStream in=new FileInputStream (”file.txt ”) 。 评分标准:本题正确给1分,不正确或不写、错误不给分也不扣分。备注:本题答案不唯一,只要是表达出使用字节流类进行文件的字节输入即可,变量名可以不同,只要符合标识符的定义即可。 4. Java 中所有类都是类 Object 的子类。 评分标准:本题正确给1分,不正确或不写、错误不给分也不扣分。备注:首字母必须大写,否则算错不给分,写对象也算正确。 5. Throwable 的两个直接子类是 Error 、 Exception ,在方法头部声明方法可能会 抛出异常使用 throws 关键字。 评分标准:本题正确给3分,不正确或不写、错误不给分也不扣分。备注:Error 、Exception 的首字母必须大写,否则算错不给分;写出对应的汉语也算正确。 6. abastract 方法是一种仅有方法头,没有具体方法体和操作实现的方法,该方法必须在 抽象类中定义。 final 方法是不能被当前类的子类重新定义的方法。 评分标准:本题正确给2分,不正确或不写、错误不给分也不扣分。备注:写出对应的汉语也算正确,例如,抽象和最终。 7. 按照功能组织类和接口的名称空间称为 package 。 评分标准:本题正确给1分,不正确或不写、错误不给分也不扣分。备注:写出对应的汉语也算正确,例如,包。 三、简答题(每小题5分,共20分) 1. 有如下程序: Moveable.java 文件中有如下代码 interface Moveable{ void move(int x,int y); void jump(int x, int y); } Monkey.java 中如下代码: class Monkey implements Moveable{ public void jump(int x,int y){ System.out.printf(“I am jumping from %d to %d ”,x,y); } 专业班级: 姓名: 学号: …………………………密………………………………封………………………………线…………………………

java编程题全集题及答案

J a v a程序设计总复习题 1、编写一个Java程序,用if-else语句判断某年份是否为闰年。(分支) // Programme Name LeapYear.java public class LeapYear{ public static void main(String args[]){ int year=2010; if(args.length!=0) year=Integer.parseInt(args[0]); if((year%4==0 && year%100!=0)||(year%400==0)) 年是闰年。"); else 年不是闰年。"); } }//if-else语句 2、编写一个Java程序在屏幕上输出1!+2!+3!+……+10!的和。(循 环) // programme name ForTest.java public class ForTest { public static void main( String args[] ) { int i,j,mul,sum=0; for(i=1;i<=10;i++) { mul=1; for(j=1,j<=i;j++) { mul=mul*j; } sum=sum+mul; } “1!+2!+3!+……+10!= ”+sum); } } 3、依次输入10个学生成绩,判断学生(优秀、良好、中等、及格、不及格) 并计算人数(switch) 4、使用冒泡排序(数组) public class BubbleSort { public static void main(String[] args) {

Java程序设计基础习题答案

Java程序设计基础课后习题参考答案 第2章 1、关于Java Application得入口方法main()得检验: main()方法得参数名就是否可以改变? main()方法得参数个数就是否可以改变? 该方法名就是否可以改变? 参考答案:(1)main()方法得参数名可以改变.(2)main()方法得参数个数不可以改变。(3)该方法名不可以改变。 2、当一个程序没有main()方法时,能编译吗?如果能编译,能运行吗? 参考答案:当一个程序没有main()方法就是,就是可以编译通过得,但就是不能给运行,因为找不到一个主函数入口。 3、下列语句能否编译通过? bytei =127; bytej = 128; longl1 = 999999; long l2= 9999999999; 参考答案:byte i 与long l1可以编译通过。而byte j 与longl2 超出自身数据类型范围,所以编译失败。 4、下列语句能否编译通过? float f1 =3、5; float f2 = 3.5f; 参考答案:java中浮点型得数据在不声明得情况下都就是double型得,如果要表示一个数据就是float型得,必须在数据后面加上“F”或“f”;因此,floatf1 无法编译通过。 5、验证int 与char,int与double等类型就是否可以相互转换。 参考答案:(1)char类型可以转换为int 类型得,但就是int类型无法转换为char类型得;(2)int 可以转换为double类型得,但就是double类型无法转换为int 类型得。 6、计算下列表达式,注意观察运算符优先级规则。若有表达式就是非法表达式,则指出不合法之处且进行解释。 (1)4+5 == 6*2 ?(2) (4=5)/6?? (3)9%2*7/3>17(4)(4+5)<=6/3 ? (5) 4+5%3!=7-2????(6)4+5/6〉=10%2 参考答案:表达式(2)为不合法表达式,只能将值赋值给一个变量,因此其中(4=5)将5赋值给4就是不合法得. 7、下列()就是合法得Java标识符。 (1)Counter1 ??(2)$index, (3) name-7 ??(4)_byte

java语言程序设计课后习题答案

习题2 3.使用“= =”对相同内容的字符串进行比较,看会产生什么样的结果。 答:首先创建一个字符串变量有两种方式:String str = new String("abc"); String str = "abc"; 使用“= =”会因为创建的形式不同而产生不同的结果: String str1 = "abc"; String str2 = "abc"; =str2); ; public class Exercise51{ public static void main(String[] args) throws IOException{ "请输入一个整数:"); InputStreamReader isStream=new InputStreamReader; BufferedReader bfReader=new BufferedReader(isStream); String input=(); int length=()-1; int n=new Integer(input).intValue(); while(length>=0){ int divisor=(int) (10,length); length=length-1; int output=n/divisor; n=n%divisor; ","); } } } 法二:(建议使用) public class Exercise5{ public static void main(String[] args){ int n=1678; int unit; int decimal; int hundred; int thousand; thousand=n/1000%10; hundred=n/100%10; decimal=n/10%10; unit=n%10; "1678包含的数字分别是: "+thousand+','+hundred+','+decimal+', '+unit); } } ;

Java程序设计预赛模拟题-2

一、单选题 1.Java JDK中调试器的命令是( )。 A. javac B. java C. jdb D. javah 2.运行jar文件中class文件需要在java命令后面加的参数为()。 A. -cp B. -g C. -d D. -verbose 3.下面哪项在java中是不合法的标识符?() A. $user B. point C. You&me D. _endline 4.下列哪一项不是Java保留字?() A. sizeof B. super C. abstract D. break 5.下列哪个布局管理器中的按钮位置有可能会根据Frame的大小改变而改变? () A. BorderLayout B. CardLayout C. GridLayout D. FlowLayout 6.下面哪些java语句会导致无限循环?( ) I. while (true) i = 0; II. while (false) i = 1; III. while (!false) i = 0; A. III only B. I and III only C. I only D. I, II and III 7.下面是Example.java文件的完整代码,请找出会产生编译错误的行()。 1) class BaseClass { 2) public String str; 3) public BaseClass(){ 4) System.out.println(“ok”);} 5) public BaseClass(String s){ 6) str=s;}} 7) class SubClass extends BaseClass{ 8) } 9) public class Example{ 10) public void method(){ 11) SubClass s=new SubClass(“hello”); 12) BaseClass b=new BaseClass(“world”); 13) } 14) } A. 7 B. 10 C. 11 D.12 8.可以在下面代码段point x处写入的是()。 //point x public class Interesting{ //do something } A. String str; B. static int PI=3.14; C. public class MyClass{//do other thing…} D. import java.awt.*; 9.下面关于事件监听的说明,哪一个语句是正确的?() A. 所有组件,都不允许附加多个监听器 B. 如果多个监听器加在一个组件上,那么事件只会触发一个监听器 C. 组件不允许附加多个监听器

Java程序设计-习题参考答案

参考答案 第1章 3、计算机系统由哪两部分组成的?计算机硬件结构由哪几部分组成?它们各自有什么作用? 一台计算机由硬件和软件组成。一台典型的计算机由五大部分组成。这五大部分是:运算器,控制器,存储器,输入设备和输出设备。 运算器是执行算术运算和逻辑运算的部件。 控制器是向计算机其他部分发送命令的部件。 存储器是计算机用来存储数据、信息的部件。 输入设备就是外界向计算机输入信息设备。 输出设备恰好与输入设备的作用相反,它将处理过后的信息输出呈现给用户。 9、将以下十进制数转换为对应的二进制数 (1)32 (2)97 (3)256 (4)500 (1)100000 (2)1100001 (3)100000000 (4)111110100 第2章 1.Java语言有哪些主要特点。 平台独立性 安全性 多线程 网络化 面向对象 3.Java Application的开发步骤有哪些。 Java Application的开发步骤: (1)下载JDK软件并安装; (2)配置相应的环境变量(path和classpath); (3)编写Java源程序(文本编辑器或集成开发环境IDE); (4)编译Java源程序,得到字节码文件(javac *.java); (5)执行字节码文件(java 字节码文件名)。

4.什么是环境变量,设置环境变量的主要目的是什么。 环境变量的配置主要是为了进行“寻径”,也即让程序能找到它需要的文件,所以设置的内容就是一些路径。 第3章 1.Java语言对于合法标识符的规定是什么?指出以下哪些为合法标识符。 a a2 3a *a _a $a int a% 在Java语言中,标识符必须以字母、美元符号或者下划线打头,后接字母、数字、下划线或美元符号串。另外,Java语言对标识符的有效字符个数不做限定。 合法的标识符: a a2 _a $a 5.数据类型强制转换的原则是什么?如何转换? 对于变窄转换,如long到short、double到float,或者不兼容转换:float到short、char 到short等,则需要进行强制转换。 float f = 11.5; short b ; b = (short)f; (强制转换) 第4章 5.用穷举法求出3位数中百、十、个位数的立方和就是该数的数。 public class Test { public static void main(String[] args) { int a,b,c,x=100; while(x<1000){ a=x%10; b=(x%100-a)/10; c=(x-x%100)/100; if(a*a*a+b*b*b+c*c*c==x) System.out.println(x); x+=1;

Java程序设计期末考试题

Java程序设计期末考试题 一、选择题 下列说法中,不正确的是( A ) A) 一个java源程序编译通过后,得到的结果文件数也只有一个。 B) 一个java源程序经过编译后,得到的文件的扩展名一定是.class。 C) 一个java源程序只能有一个public class类定义,且源文件的名字与public class的类名相同,扩展名必须是.java。 D) 一个java源程序可以包含多个class类。 请问,以下哪些描述是正确的? 请选择所有正确答案: (1)如果package语句存在,则必须出现在源文件的非空白首行。(2)如果import语句存在,则必须出现在源文件的非空白首行。(3)如果main()方法存在,则必须出现在源文件的非空白首行。(4)如果在源文件中声明了一个public接口,则其名称必须和源文件名一致。 请问,以下哪些是Java中的合法标识符? 请选择所有正确答案: (1)my-id (2)my_id

(3)101ids (4)id101 请问,以下哪些是合法的标识符? 请选择所有正确答案: (1)%abcd (2)$abcd (3)1abcd (4)package (5)_a_long_name 以下哪个不是Java的关键字?() A、FALSE B、const C、this D、void 以下哪个不是Java的关键字?() A、TRUE B、goto C、this D、void Java的字符类型采用的是Unicode编码方案,每个Unicode码占用()个比特位。 A、8 B、16

C、32 D、64 请问一下哪些修饰符用于声明一个常量?请选择一个正确答案:static final abstract public 给出以下代码,该程序的运行结果是什么? public class Example{ final int x=0; Example(){ x=1; } final int aMethod(){ return x; } } 请选择所有正确答案: 代码编译错误,因为非final类中存在final方法。 代码编译成功。

相关主题
文本预览
相关文档 最新文档