如何调试跟踪Android Framework源代码本文讲解如何在Eclipse中导入Android源代码(包括Framework和Applicationjava实现代码跟踪的代码)java实现代码跟踪,然后通过模拟器或真机跟踪/调试Android的Java代码,区别于一般基于Android SDK的纯应用开发,这里可以跟踪/调试Framework中的代码 。
一、准备工作
确保机器上已经安装并配置下列软件环境:JDK/ Eclipse / Android SDK / ADT
即 , 机器上已经安装了Eclipse下Android应用开发所需的环境 。如果还未配置,移步《搭建Windows下Android应用开发环境——Eclipse/Android/ADT》 。
另外 , 为了跟踪调试Android源码 , 你还需要有Android源码,并有源码的编译环境,可以是:
虚拟机环境 虚拟机中安装Linux,Linux下编译Android源码 。此环境下 , 如果要在宿主机的Eclipse中调试,还需要把Android的源码路径共享出来,宿主机可访问到java实现代码跟踪;
有单独的可编译Android的网络环境 在你的客户端的机器上访问服务器共享出来的Android的源码路径;
Linux环境下直接通过Eclipse跟踪调试本机上的Android源码 。
注意:不管哪种工作方式,Android源码要都是已经编译过的,且编译时采用的是Eng模式(vs User mode) 。编译Android Platform和Kernel的过程,可参考《Ubuntu10.10下编译Android2.2平台》及《Ubuntu10.10下编译Android2.2内核》 。
二、基本设置
准备工作完毕之后,现在做一些基本的设置 。
1. 把Android源码路径Android_ROOT下的development\ide\eclipse中的.classpath文件复制到Android_ROOT下;如果需要在模拟器中进行调试的话,需要复制三个img(具体方法见)
2. 修改Eclipse的设置
修改eclipse.ini文件 , 更改下列内容:
[plain] view plaincopy
-Xms40m
-Xmx384m
改为:
[java] view plaincopy
-Xms128m
-Xmx512m
这里增大最小Java堆大小到128MB,增大最大Java堆大小到512MB 。
三、Eclipse中创建工程
1. FileNewJava Project
2. 输入项目名
3. 取消Use default location,并在Location中输入或选择Android源码路径Android_ROOT
4. 选择NextFinish 。会有一个漫长的等待过程
新建的工程可能会有错误,根据错误提示,加入或者删除项目中配置的程序包 。
四、调试环境配置
1. 右击刚刚在#3中创建的项目;
2. 选择:Debug AsDebug Configurations…;
3. 右击“Remote Java Application”,选择New 。或者直接双击“Remote Java Application”创建一个新的Remote Application 。
4. 填入Name;Project选择刚刚创建的项目Android2.3.7;端口填写8700(不一定是8700,到DDMS Perspective下的Device View中看所需的端口号) 。
5. Apply保存,然后退出 。
五、调试
可以通过模拟器或者真机调试 。
无论模拟器还是真机,都要:
【java实现代码跟踪 java代码走查标准】先启动机器(模拟器启动,或真机打开 , 并通过USB与PC正常连接),也就是要在DDMS Perspective的Devices视图中看到有机器连接;
确保运行中的代码与你要调试的代码是一样的 。
假如,我们想要跟踪锁屏解锁的调用情况 。
我们知道解锁的实现是在LockScreen.java的onGrabbedStateChange()函数 , 运行在system_process进程中 。
那么,
1.在onGrabbedStateChange()中要调试的地方设置断点;
2.在Device View中,选中system_process,并点击小爬虫图标;
3.用Section#4创建的Debug配置,Debug;
4.在模拟器或真机上,执行到解锁操作时,代码就会停在断点处;
这样你就可以,
把鼠标放在某个变量上,看它的值 。也可以Eclipse中的各种调试手段调试你的代码 。
通过Step Into / Step Over / Resume / Suspend / Terminate等在Debug View中控制程序的执行 。
总结
通过本文可以:
本文讲解是基于Windows环境的,但是不仅适用于Windows环境 , 同样适用于Mac OS和Linux系统,只是一些路径和使用方式有差别;
可以跟踪/调试所有Android中Java的源码(无论Framework的代码,还是App中的代码),并不能Debug Framework中的c/ccode;
为了使整个项目在Eclipse中都能编译过,.classpath中也包含了out/里编译生成的内容,所以必须保证Android源码是已经编译过的 。
跟踪/调试的前提是要在所要调试代码处设置断点 , 并知道该处代码执行在哪个进程中 。
===================================================================================================================
如果导入的工程有错误,可以参照下面方法操作 。
===================================================================================================================
我们导入一个android自带应用的工程时,往往有很多错误 。以自带的 AlarmClock 为例,导入eclipse后,往往出现很多错误,如下图所示:
例如,上图中的Intent.ACTION_ALARM_CHANGED 无法访问,下面我们就找到源代码看看原因何在?
根据java 编程规范,我们知道这个api (静态变量)被隐藏掉了 , 所以在sdk中无法使用 。在知道了原因之后,我们有几种解决方案(建议使用方法二):
1. 自己将源代码中的@hide去掉,然后编译一个sdk来替换默认的sdk 。
在linux上使用make PRODUCT-sdk-sdk 命令,编译一个新的sdk出来,注意编译后其实我们不需要整个sdk,只需要android.jar这个文件替换掉sdk里的android.jar,例如:笔者的sdk里的jar对应的目录为:
F:/Program Files/Android/android-sdk-windows/platforms/android-8/android.jar
具体编译sdk的方法是,在linux编译环境下用命令 make PRODUCT-sdk-sdk , 成功后,会有如下提示:
Package SDK: out/host/linux-x86/sdk/android-sdk_eng.stevewang_linux-x86.zip
我们进入到 linux编译环境的 out/host/linux-x86/sdk/android-sdk_eng.stevewang_linux-x86/platforms/android-2.2/目录下可以看到android.jar 文件 。使用此文件替换F:/Program Files/Android/android-sdk-windows/platforms/android-8/android.jar 即可 。替换前记得备份
此方法较为麻烦,建议使用方法二
2. 添加framework 编译出来的class.jar文件到 eclipse的build path
其实在编译android的时候,我们将framework 编译到一个临时的jar包中了,这个jar包的路径一般为:
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
[font='dejavu]我们只需要在linux上android源代码目录下使用make 命令即可生成此文件 。
[font='dejavu]
[font='dejavu]由于这个jar文件中的api 还没有重新打包,里面被@hide掉的api并没有被去掉 。所以我们依然能够引用里面
[font='dejavu]被@hide的api。而sdk 中的android.jar文件时重新打包生成的 , 其里标记有@hide的api已经被去掉了 。
[font='dejavu]所以我们把 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar 拷贝到本地pc上 。
然后在工程中添加此jar包 。
具体方法:
1 . 拷贝linux编译生成的out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar到本机PC 。
2,在eclipse的Android项目中,选择项目属性-Java Build Path-Libraries-Add Library-User Library-Next- UserLibraries进入到User Libraries管理界面,点击New新建一个User Library , 比如android_framework,点击Add Jars把Jar包加入到建立的User Library中,最后点击OK 。
3.选择项目属性-Java Build Path-Order and Export,把所建立的User Libraries移到Android SDK的上面 。
如下图:
之后我们的工程错误消失了:
如何跟踪java代码的执行很简单,单元测试?。∫氚?import org.junit.Test;
比如下面这个测试函数,不是main函数,但是你可以执行它并测试输出 。注意要有@标识 , 这是注释,必要的 。还有就是可以打断点?。《系憔褪侵葱型V沟牡胤?,可以是程序某个模块 , 某个变量值等 。
@Test
public void selectUserByID() {
// 得到SqlSession实例,便于执行增删改查、事务提交回滚等操作 。
SqlSession session = getSqlSessionFactory().openSession();
try {
userPOJO user = (userPOJO) session.selectOne("mapper.userPOJO.selectByName", 2);
System.out.println(user);
} finally {
session.close();
}
}
我刚学Java不久 用的是eclipse但是全部是英文 怎么用它来设置断点一步一步跟踪调试啊 谢谢大家了这个说起来很麻烦的 最好找一本书来看看 大概是这样的 在java实现代码跟踪你需要设断点的地方双击鼠标java实现代码跟踪,出现一个小圆点 , 在debug模式下运行它 就进入java实现代码跟踪了调试跟踪的状态了 如果不懂最好看看相关的书
java语言中 , 四种会话跟踪技术分别是什么?答:会话作用域ServletsJSP页面描述
page否是代表与一个页面相关的对象和属性 。一个页面由一个编译好的Javaservlet类(可以带有任何的include指令,但是没有include动作)表示 。这既包括servlet又包括被编译成servlet的JSP页面
request是是代表与Web客户机发出的一个请求相关的对象和属性 。一个请求可能跨越多个页面,涉及多个Web组件(由于forward指令和include动作的关系)
session是是代表与用于某个Web客户机的一个用户体验相关的对象和属性 。一个Web会话可以也经常会跨越多个客户机请求
application是是代表与整个Web应用程序相关的对象和属性 。这实质上是跨越整个Web应用程序,包括多个页面、请求和会话的一个全局作用域
java里面跟踪函数调用可以用什么的执行速度慢上约20倍 。无论什么都不能阻止Java语言进行编译 。写作本书的时候java实现代码跟踪,刚刚出现java实现代码跟踪了一些准实时编译器,它们能显著加快速度 。当然,java实现代码跟踪我们完全有理由认为会出现适用于更多流行平台的纯固有编译器,但假若没有那些编译器,由于速度的限制,必须有些问题是Java不能解决的 。
(2) 和C一样,Java也提供了两种类型的注释 。
(3) 所有东西都必须置入一个类 。不存在全局函数或者全局数据 。如果想获得与全局函数等价的功能,可考虑将static方法和static数据置入一个类里 。注意没有象结构、枚举或者联合这一类的东西,一切只有“类”(Class)!
(4) 所有方法都是在类的主体定义的 。所以用C的眼光看,似乎所有函数都已嵌入 , 但实情并非如何(嵌入的问题在后面讲述) 。
(5) 在Java中,类定义采取几乎和C一样的形式 。但没有标志结束的分号 。没有class foo这种形式的类声明,只有类定义 。
class aType()
void aMethod()
}
(6) Java中没有作用域范围运算符“::” 。Java利用点号做所有的事情,但可以不用考虑它,因为只能在一个类里定义元素 。即使那些方法定义,也必须在一个类的内部 , 所以根本没有必要指定作用域的范围 。我们注意到的一项差异是对static方法的调用:使用ClassName.methodName() 。除此以外 , package(包)的名字是用点号建立的,并能用import关键字实现C的“
import java.awt.*;
(
(7) 与C类似,Java含有一系列“主类型”(Primitive type),以实现更有效率的访问 。在Java中 , 这些类型包括boolean,char,byte,short,int,long,float以及double 。所有主类型的大小都是固有的,且与具体的机器无关(考虑到移植的问题) 。这肯定会对性能造成一定的影响,具体取决于不同的机器 。对类型的检查和要求在Java里变得更苛刻 。例如:
■条件表达式只能是boolean(布尔)类型 , 不可使用整数 。
■必须使用象X Y这样的一个表达式的结果;不能仅仅用“X Y”来实现“副作用” 。
(8) char(字符)类型使用国际通用的16位Unicode字符集,所以能自动表达大多数国家的字符 。
(9) 静态引用的字串会自动转换成String对象 。和C及C不同 , 没有独立的静态字符数组字串可供使用 。
(10) Java增添了三个右移位运算符“”,具有与“逻辑”右移位运算符类似的功用,可在最末尾插入零值 。“”则会在移位的同时插入符号位(即“算术”移位) 。
(11) 尽管表面上类似 , 但与C相比,Java数组采用的是一个颇为不同的结构,并具有独特的行为 。有一个只读的length成员,通过它可知道数组有多大 。而且一旦超过数组边界,运行期检查会自动丢弃一个异常 。所有数组都是在内存“堆”里创建的,我们可将一个数组分配给另一个(只是简单地复制数组句柄) 。数组标识符属于第一级对象,它的所有方法通常都适用于其java实现代码跟踪他所有对象 。
(12) 对于所有不属于主类型的对象,都只能通过new命令创建 。和C不同 , Java没有相应的命令可以“在堆栈上”创建不属于主类型的对象 。所有主类型都只能在堆栈上创建 , 同时不使用new命令 。所有主要的类都有自己的“封装(器)”类,所以能够通过new创建等价的、以内存“堆”为基础的对象(主类型数组是一个例外:它们可象C那样通过集合初始化进行分配,或者使用new) 。
(13) Java中不必进行提前声明 。若想在定义前使用一个类或方法,只需直接使用它即可--编译器会保证使用恰当的定义 。所以和在C中不同,我们不会碰到任何涉及提前引用的问题 。
(14) Java没有预处理机 。若想使用另一个库里的类 , 只需使用import命令,并指定库名即可 。不存在类似于预处理机的宏 。
(15) Java用包代替了命名空间 。由于将所有东西都置入一个类 , 而且由于采用了一种名为“封装”的机制 , 它能针对类名进行类似于命名空间分解的操作,所以命名的问题不再进入我们的考虑之列 。数据包也会在单独一个库名下收集库的组件 。我们只需简单地“import”(导入)一个包,剩下的工作会由编译器自动完成 。
(16) 被定义成类成员的对象句柄会自动初始化成null 。对基本类数据成员的初始化在Java里得到了可靠的保障 。若不明确地进行初始化,它们就会得到一个默认值(零或等价的值) 。可对它们进行明确的初始化(显式初始化):要么在类内定义它们,要么在构建器中定义 。采用的语法比C的语法更容易理解,而且对于static和非static成员来说都是固定不变的 。我们不必从外部定义static成员的存储方式,这和C是不同的 。
(17) 在Java里,没有象C和C那样的指针 。用new创建一个对象的时候,会获得一个引用(本书一直将其称作“句柄”) 。例如:
String s = new String("howdy");
然而,C引用在创建时必须进行初始化,而且不可重定义到一个不同的位置 。但Java引用并不一定局限于创建时的位置 。它们可根据情况任意定义,这便消除了对指针的部分需求 。在C和C里大量采用指针的另一个原因是为了能指向任意一个内存位置(这同时会使它们变得不安全 , 也是Java不提供这一支持的原因) 。指针通常被看作在基本变量数组中四处移动的一种有效手段 。Java允许我们以更安全的形式达到相同的目标 。解决指针问题的终极方法是“固有方法”(已在附录A讨论) 。将指针传递给方法时,通常不会带来太大的问题,因为此时没有全局函数 , 只有类 。而且我们可传递对对象的引用 。Java语言最开始声称自己“完全不采用指针!”但随着许多程序员都质问没有指针如何工作?于是后来又声明“采用受到限制的指针” 。大家可自行判断它是否“真”的是一个指针 。但不管在何种情况下,都不存在指针“算术” 。
(18) Java提供了与C类似的“构建器”(Constructor) 。如果不自己定义一个,就会获得一个默认构建器 。而如果定义了一个非默认的构建器,就不会为我们自动定义默认构建器 。这和C是一样的 。注意没有复制构建器,因为所有自变量都是按引用传递的 。
(19) Java中没有“破坏器”(Destructor) 。变量不存在“作用域”的问题 。一个对象的“存在时间”是由对象的存在时间决定的,并非由垃圾收集器决定 。有个finalize()方法是每一个类的成员,它在某种程度上类似于C的“破坏器” 。但finalize()是由垃圾收集器调用的,而且只负责释放“资源”(如打开的文件、套接字、端口、URL等等) 。如需在一个特定的地点做某样事情,必须创建一个特殊的方法,并调用它,不能依赖finalize() 。而在另一方面,C中的所有对象都会(或者说“应该”)破坏,但并非Java中的所有对象都会被当作“垃圾”收集掉 。由于Java不支持破坏器的概念,所以在必要的时候,必须谨慎地创建一个清除方法 。而且针对类内的基础类以及成员对象,需要明确调用所有清除方法 。
(20) Java具有方法“过载”机制,它的工作原理与C函数的过载几乎是完全相同的 。
(21) Java不支持默认自变量 。
(22) Java中没有goto 。它采取的无条件跳转机制是“break 标签”或者“continue 标准” , 用于跳出当前的多重嵌套循环 。
(23) Java采用了一种单根式的分级结构,因此所有对象都是从根类Object统一继承的 。而在C中,我们可在任何地方启动一个新的继承树,所以最后往往看到包含了大量树的“一片森林” 。在Java中,我们无论如何都只有一个分级结构 。尽管这表面上看似乎造成了限制,但由于我们知道每个对象肯定至少有一个Object接口,所以往往能获得更强大的能力 。C目前似乎是唯一没有强制单根结构的唯一一种OO语言 。
(24) Java没有模板或者参数化类型的其他形式 。它提供了一系列集合:Vector(向量),Stack(堆栈)以及Hashtable(散列表),用于容纳Object引用 。利用这些集合,我们的一系列要求可得到满足 。但这些集合并非是为实现象C“标准模板库”(STL)那样的快速调用而设计的 。Java 1.2中的新集合显得更加完整,但仍不具备正宗模板那样的高效率使用手段 。
(25) “垃圾收集”意味着在Java中出现内存漏洞的情况会少得多,但也并非完全不可能(若调用一个用于分配存储空间的固有方法,垃圾收集器就不能对其进行跟踪监视) 。然而 , 内存漏洞和资源漏洞多是由于编写不当的finalize()造成的,或是由于在已分配的一个块尾释放一种资源造成的(“破坏器”在此时显得特别方便) 。垃圾收集器是在C基础上的一种极大进步,使许多编程问题消弥于无形之中 。但对少数几个垃圾收集器力有不逮的问题,它却是不大适合的 。但垃圾收集器的大量优点也使这一处缺点显得微不足道 。
(26) Java内建了对多线程的支持 。利用一个特殊的Thread类,我们可通过继承创建一个新线程(放弃了run()方法) 。若将synchronized(同步)关键字作为方法的一个类型限制符使用,相互排斥现象会在对象这一级发生 。在任何给定的时间 , 只有一个线程能使用一个对象的synchronized方法 。在另一方面,一个synchronized方法进入以后,它首先会“锁定”对象,防止其他任何synchronized方法再使用那个对象 。只有退出了这个方法,才会将对象“解锁” 。在线程之间,我们仍然要负责实现更复杂的同步机制,方法是创建自己的“监视器”类 。递归的synchronized方法可以正常运作 。若线程的优先等级相同,则时间的“分片”不能得到保证 。
(27) 我们不是象C那样控制声明代码块,而是将访问限定符(public , private和protected)置入每个类成员的定义里 。若未规定一个“显式”(明确的)限定符,就会默认为“友好的”(friendly) 。这意味着同一个包里的其他元素也可以访问它(相当于它们都成为C的“friends”--朋友),但不可由包外的任何元素访问 。类--以及类内的每个方法--都有一个访问限定符,决定它是否能在文件的外部“可见” 。private关键字通常很少在Java中使用,因为与排斥同一个包内其他类的访问相比 , “友好的”访问通常更加有用 。然而 , 在多线程的环境中,对private的恰当运用是非常重要的 。Java的protected关键字意味着“可由继承者访问,亦可由包内其他元素访问” 。注意Java没有与C的protected关键字等价的元素,后者意味着“只能由继承者访问”(以前可用“private protected”实现这个目的,但这一对关键字的组合已被取消了) 。
(28) 嵌套的类 。在C中 , 对类进行嵌套有助于隐藏名称,并便于代码的组织(但C的“命名空间”已使名称的隐藏显得多余) 。Java的“封装”或“打包”概念等价于C的命名空间,所以不再是一个问题 。Java 1.1引入了“内部类”的概念,它秘密保持指向外部类的一个句柄--创建内部类对象的时候需要用到 。这意味着内部类对象也许能访问外部类对象的成员,毋需任何条件--就好象那些成员直接隶属于内部类对象一样 。这样便为回调问题提供了一个更优秀的方案--C是用指向成员的指针解决的 。
(29) 由于存在前面介绍的那种内部类,所以Java里没有指向成员的指针 。
(30) Java不存在“嵌入”(inline)方法 。Java编译器也许会自行决定嵌入一个方法,但我们对此没有更多的控制权力 。在Java中,可为一个方法使用final关键字,从而“建议”进行嵌入操作 。然而 , 嵌入函数对于C的编译器来说也只是一种建议 。
(31) Java中的继承具有与C相同的效果,但采用的语法不同 。Java用extends关键字标志从一个基础类的继承,并用super关键字指出准备在基础类中调用的方法,它与我们当前所在的方法具有相同的名字(然而,Java中的super关键字只允许我们访问父类的方法--亦即分级结构的上一级) 。通过在C中设定基础类的作用域 , 我们可访问位于分级结构较深处的方法 。亦可用super关键字调用基础类构建器 。正如早先指出的那样 , 所有类最终都会从Object里自动继承 。和C不同,不存在明确的构建器初始化列表 。但编译器会强迫我们在构建器主体的开头进行全部的基础类初始化,而且不允许我们在主体的后面部分进行这一工作 。通过组合运用自动初始化以及来自未初始化对象句柄的异常,成员的初始化可得到有效的保证 。
1045页程序
(32) Java中的继承不会改变基础类成员的保护级别 。我们不能在Java中指定public , private或者protected继承,这一点与C是相同的 。此外,在衍生类中的优先方法不能减少对基础类方法的访问 。例如,假设一个成员在基础类中属于public,而我们用另一个方法代替了它 , 那么用于替换的方法也必须属于public(编译器会自动检查) 。
(33) Java提供了一个interface关键字,它的作用是创建抽象基础类的一个等价物 。在其中填充抽象方法,且没有数据成员 。这样一来,对于仅仅设计成一个接口的东西 , 以及对于用extends关键字在现有功能基础上的扩展,两者之间便产生了一个明显的差异 。不值得用abstract关键字产生一种类似的效果,因为我们不能创建属于那个类的一个对象 。一个abstract(抽象)类可包含抽象方法(尽管并不要求在它里面包含什么东西),但它也能包含用于具体实现的代码 。因此,它被限制成一个单一的继承 。通过与接口联合使用,这一方案避免了对类似于C虚拟基础类那样的一些机制的需要 。
为创建可进行“例示”(即创建一个实例)的一个interface(接口)的版本,需使用implements关键字 。它的语法类似于继承的语法,如下所示:
1046页程序
(34) Java中没有virtual关键字 , 因为所有非static方法都肯定会用到动态绑定 。在Java中,程序员不必自行决定是否使用动态绑定 。C之所以采用了virtual,是由于我们对性能进行调整的时候,可通过将其省略,从而获得执行效率的少量提升(或者换句话说:“如果不用 , 就没必要为它付出代价”) 。virtual经常会造成一定程度的混淆,而且获得令人不快的结果 。final关键字为性能的调整规定了一些范围--它向编译器指出这种方法不能被取代,所以它的范围可能被静态约束(而且成为嵌入状态,所以使用C非virtual调用的等价方式) 。这些优化工作是由编译器完成的 。
(35) Java不提供多重继承机制(MI),至少不象C那样做 。与protected类似 , MI表面上是一个很不错的主意,但只有真正面对一个特定的设计问题时,才知道自己需要它 。由于Java使用的是“单根”分级结构,所以只有在极少的场合才需要用到MI 。interface关键字会帮助我们自动完成多个接口的合并工作 。
(36) 运行期的类型标识功能与C极为相似 。例如,为获得与句柄X有关的信息,可使用下述代码:
X.getClass().getName();
为进行一个“类型安全”的紧缩造型,可使用:
derived d = (derived)base;
这与旧式风格的C造型是一样的 。编译器会自动调用动态造型机制,不要求使用额外的语法 。尽管它并不象C的“new casts”那样具有易于定位造型的优点,但Java会检查使用情况,并丢弃那些“异常”,所以它不会象C那样允许坏造型的存在 。
(37) Java采取了不同的异常控制机制,因为此时已经不存在构建器 。可添加一个finally从句,强制执行特定的语句,以便进行必要的清除工作 。Java中的所有异常都是从基础类Throwable里继承而来的,所以可确保我们得到的是一个通用接口 。
1047页程序
(38) Java的异常规范比C的出色得多 。丢弃一个错误的异常后,不是象C那样在运行期间调用一个函数 , Java异常规范是在编译期间检查并执行的 。除此以外,被取代的方法必须遵守那一方法的基础类版本的异常规范:它们可丢弃指定的异常或者从那些异常衍生出来的其他异常 。这样一来 , 我们最终得到的是更为“健壮”的异常控制代码 。
(39) Java具有方法过载的能力,但不允许运算符过载 。String类不能用 和 =运算符连接不同的字串,而且String表达式使用自动的类型转换,但那是一种特殊的内建情况 。
(40) 通过事先的约定,C中经常出现的const问题在Java里已得到了控制 。我们只能传递指向对象的句柄,本地副本永远不会为我们自动生成 。若希望使用类似C按值传递那样的技术,可调用clone(),生成自变量的一个本地副本(尽管clone()的设计依然尚显粗糙--参见第12章) 。根本不存在被自动调用的副本构建器 。为创建一个编译期的常数值,可象下面这样编码:
static final int SIZE = 255
static final int BSIZE = 8 * SIZE
(41) 由于安全方面的原因 , “应用程序”的编程与“程序片”的编程之间存在着显著的差异 。一个最明显的问题是程序片不允许我们进行磁盘的写操作,因为这样做会造成从远程站点下载的、不明来历的程序可能胡乱改写我们的磁盘 。随着Java 1.1对数字签名技术的引用,这一情况已有所改观 。根据数字签名,我们可确切知道一个程序片的全部作者 , 并验证他们是否已获得授权 。Java 1.2会进一步增强程序片的能力 。
(42) 由于Java在某些场合可能显得限制太多,所以有时不愿用它执行象直接访问硬件这样的重要任务 。Java解决这个问题的方案是“固有方法”,允许我们调用由其他语言写成的函数(目前只支持C和C) 。这样一来,我们就肯定能够解决与平台有关的问题(采用一种不可移植的形式,但那些代码随后会被隔离起来) 。程序片不能调用固有方法,只有应用程序才可以 。
(43) Java提供对注释文档的内建支持,所以源码文件也可以包含它们自己的文档 。通过一个单独的程序,这些文档信息可以提取出来 , 并重新格式化成HTML 。这无疑是文档管理及应用的极大进步 。
(44) Java包含了一些标准库,用于完成特定的任务 。C则依靠一些非标准的、由其他厂商提供的库 。这些任务包括(或不久就要包括):
■连网
■数据库连接(通过JDBC)
■多线程
■分布式对象(通过RMI和CORBA)
■压缩
■商贸
由于这些库简单易用 , 而且非常标准,所以能极大加快应用程序的开发速度 。
(45) Java 1.1包含了Java Beans标准,后者可创建在可视编程环境中使用的组件 。由于遵守同样的标准,所以可视组件能够在所有厂商的开发环境中使用 。由于我们并不依赖一家厂商的方案进行可视组件的设计,所以组件的选择余地会加大,并可提高组件的效能 。除此之外,Java Beans的设计非常简单,便于程序员理解;而那些由不同的厂商开发的专用组件框架则要求进行更深入的学习 。
(46) 若访问Java句柄失败,就会丢弃一次异常 。这种丢弃测试并不一定要正好在使用一个句柄之前进行 。根据Java的设计规范,只是说异常必须以某种形式丢弃 。许多C运行期系统也能丢弃那些由于指针错误造成的异常 。
(47) Java通常显得更为健壮 , 为此采取的手段如下:
■对象句柄初始化成null(一个关键字)
■句柄肯定会得到检查,并在出错时丢弃异常
■所有数组访问都会得到检查,及时发现边界违例情况
■自动垃圾收集,防止出现内存漏洞
■明确、“傻瓜式”的异常控制机制
■为多线程提供了简单的语言支持
■对网络程序片进行字节码校验
另外,团IDC网上有许多产品团购,便宜有口碑
在java中能否像在c语言中一样进行分步跟踪?eclipse里边有单步调试
可以鼠标双击代码左侧可以显示行数的那个地方,就可以加上一个点,那个点就是断点了 ,
调试的时候点击Debug,就行了,
单步调试可以F5 或者 F6
F5是进去调试,对于一个方法 , 调试的时候就进去了
F6是跳跃调试,对于一个方法,程序不执行进去 , 只返回结果
java实现代码跟踪的介绍就聊到这里吧 , 感谢你花时间阅读本站内容,更多关于java代码走查标准、java实现代码跟踪的信息别忘了在本站进行查找喔 。
推荐阅读
- 常用的erp管理系统解决方案,erp系统管理功能
- 模拟飞机在水里飞行的游戏,水上飞机模拟器
- 企业如何使用定制chatgpt,企业定制服务平台
- oracle日期怎么增加 oracle中日期的加减
- 仙剑奇侠传单机游戏下载,仙剑奇侠传单机安卓版下载
- 无法sqlserver2012,无法无天的动物猜一生肖
- 推荐一些的格斗游戏电脑,格斗类电脑单机游戏
- mysql怎么转码 mysql 转decimal
- asp.netcsv转换excel文件下载的简单介绍