「java程序调试」java程序调试分析怎么写
今天给各位分享java程序调试的知识,其中也会对java程序调试分析怎么写进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
java 程序调试
分类: 电脑/网络 程序设计 其他编程语言
问题描述:
我的aa.txt文件中的内容如下:
123
2.3
true
用
int i=din.readInt();
float f=din.readFloat();
boolean b=din.readBoolean();
读取是不正确的,因文本文件中的数据是字符型,有哪位高手,能将文本文件中的数据读取后转换成对应的int ,float, boolean型
请教 请教。
一定有分加,
谢谢!
import java.io.*;
public class File5
{
public static void main(String[] args)throws IOException
{
int ch;
File file1=new File("E:\\javatest\\aa.txt");
File file2=new File("E:\\javatest\\aaa.txt");
try
{
FileInputStream fin= new FileInputStream(file1);
DataInputStream din =new DataInputStream(fin);
int i=din.readInt();
float f=din.readFloat();
boolean b=din.readBoolean();
din.close();
FileOutputStream fout= new FileOutputStream(file2);
DataOutputStream dout =new DataOutputStream(fout);
dout.writeInt(i);
dout.writeFloat(f);
dout.writeBoolean(b);
dout.close();
System.out.println("整数: "+i);
System.out.println("浮点数: "+f);
System.out.println("布尔量: "+b);
}
catch (FileNotFoundException e)
{ System.out.println(e);}
catch (IOException e)
{ System.out.println(e);}
}
}
解析:
只是按照你的要求改的,你看看吧。
import java.io.*;
public class File5
{
public static void main(String[] args)throws IOException
{
byte buf[]=new byte[15];
File file1=new File("E:\\javatest\\aa.txt");
File file2=new File("E:\\javatest\\aaa.txt");
try
{
FileInputStream fin= new FileInputStream(file1);
DataInputStream din =new DataInputStream(fin);
fin.read(buf, 0,10);
String str=new String(buf,0,3);
int i=Integer.parseInt(str);
int i=din.readInt();
str=new String(buf,5,3);
float f=Float.parseFloat(str);
float f=din.readFloat();
boolean b=din.readBoolean();
din.close();
FileOutputStream fout= new FileOutputStream(file2);
DataOutputStream dout =new DataOutputStream(fout);
dout.writeChars(Integer.toString(i));
dout.writeChars(Float.toString(f));
if(b)
str="true";
else
str="false";
dout.writeChars(str);
dout.close();
System.out.println("整数: "+i);
System.out.println("浮点数: "+f);
System.out.println("布尔量: "+b);
}
catch (FileNotFoundException e)
{ System.out.println(e);}
catch (IOException e)
{ System.out.println(e);}
}
}
JAVA调试技术
这份材料介绍JAVA的调试技术 范围涵盖普通程序和服务器端程序的调试 很多程序员并没有认识到排除软件的错误的价值 如果你是一个JAVA开发者 就很值得读一读这个材料 在现代工具的帮助下 开发者成为一个好的调试者和成为一个好的程序员的重要性一样 这个材料假设你已经有基本的JAVA编程的知识 如果你精通JAVA 这个材料也可以增加你很多知识 如果你有其他语言的调试经验 你可以跳过基本知识部分 即使是高级程序员开发的小程序也可能包含错误 你只需要理解调试的概念并熟悉合适的工具就可以成为好的调试者 这份材料将讲解JAVA调试的基本概念 也讨论高级的调试类型 我们将浏览不同的技术并且提供一些好的建议去帮助避免 追踪并最终修正程序的错误 我们将通过一个调试范例以使你熟悉调试技术 我们也将使用开发源代码工具Jikes 和JDB向你演示如何调试服务器端和客户端程序 为了编译和运行范例代码 你需要先安装一个Java Development Kit (JDK) 你可以参考后面的部分获得Jikes 和 JDB调试器 关于作者 如果对这个材料的内容有任何问题 你可以联系作者Laura Bennett 如果对中文版的翻译有何意见和建议 请联系翻译者cherami Laura Bennett 是IBM的资深软件工程师 她获得Pace大学的计算机科学学士学位和Columbia大学的计算机科学硕士学位 她是developerWorks的JAVA传教士 同时也是站点的建设者 在他的空余时间 她喜欢和她的Lego MindStorm 机器人玩乐以及和她四岁大的TinkerToys搭建物体 Cherami是一个软件工程师 闲暇之余翻译一些计算机文献 以期为中国的计算机软件事业做出一点微薄的贡献 调试的基础知识 开始的情况 在JAVA语言的早期 一个典型的开发者使用非常陈旧的方法调试程序 使用System out println() 方法 代码的跟踪信息被打印到控制台 文件或者套接字 很少有人能在第一次就写出完美的(没有任何错误)代码 因此 市场认识到了对于像C++ 程序员使用的调试器那样的工具的需要 Java开发者现在有很多调试工具可以选择 选择什么样的工具依赖于你的技术等级 通常新手使用GUI调试工具而有更多经验的程序员趋向于避免使用所见即所得的工具而更关心有更多的控制能力 没有哪个开发者不使用任何调试工具 调试器允许你穿越代码 冻结输出以及检查变量 开发者越有经验 调试工具越可以帮助他更快定位程序问题的位置 Java调试器的类型 这里有几种Java调试技术的工具: IDE(集成开发环境) 包含它们自己的调试器 (例如IBM的VisualAge for Java Symantec Visual Café以及 Borland JBuilder) 单独的GUI工具 (例如Jikes Java 平台调试器 javadt 以及JProbe) 基于文本和命令行的工具 (例如Sun JDB) 野蛮的使用编辑器 (例如Notepad 或者 VI) 检查堆栈描绘(stack traces)你使用的 JDK JSDI JSP 和HTML对你的选择都有影响 IDE 和独立的GUI 调试器对于初学者是最容易的并且被证明是最节省时间的 调试器将引导你到程序崩溃的地方 在调试器里面执行程序 使用鼠标设置断点并穿越代码 使用这些调试器的不利方面是并非所有的IDE调试器都支持最新的Java API和技术 (例如servlets 和 EJB 组件) 基于文本和野蛮的使用编辑器的技术提供更多的控制但是对于没有太多经验的程序员可能会花费更长的时间找出错误 我们称它们为 可怜人的 调试方法 如果上面的都不满足你的需求 Java平台引入Java Debugging APIs使你可以创建符合你自己特定需求的调试器 调试类型 这儿有很多调试方法 无论是在客户端还是服务器端 我们在这个材料里面包含下面的方法: 基本的Java字节码 (也就是使用System out println()) 使用注释 附加在一个正在运行的程序上 远程调试 需求调试(Debugging on demand) 优化代码的调试 Servlet JSP 文件以及EJB 组件的调试在后面会详细说明每一种类型的调试 共同的错误类型 为了给你一个你将遇到什么的提示 我们在下面列出了开发者一次又一次遇到的编辑或句法错误 是你最先和最容易遇到的错误 它们通常是键入错误引起的 逻辑错误 不同于运行时错误 因为没有任何异常被抛出 但是输出不是期望的东西 这些错误的范围从缓冲区溢出到内存泄漏 运行时错误 在程序执行时发生并且通常产生一个Java异常 线程错误 是最难重复和跟踪的 Java debugging APIs Sun已经定义了调试的结构 它们称之为JBUG 这是为了回应对真正的Java调试器的需要做出的 这些APIs帮助程序员建立符合自己需要的调试器: 接口应该和语言的风格一样是面向对象的 例如线程和监视器这样的Java运行时特性应该被前面的支持 可以进行远程调试 在通常操作下的安全性不能被损害 修正的Java Debugger (JDB) 既是体现Java Debugging API的概念 同时又是一个有用的调试工具 它用Java Debug Interface (JDI)重写并且是JDK的一部分 JDB将在后面详细讨论 准备一个调试用的程序 Java平台为调试过程提供语言支持 你在用编译器编译你的程序时可以用编译选项指示编译器在目标文件中产生符号信息 如果你使用其它的编译器而不是javac 参考你的编译器的文档获得如何生成带有调试信息的目标文件 如果你使用javac 编译器创建调试代码 使用 g 编译选项 这个选项让你在调试的时候可以检查本机类实例和静态变量 如果你没有使用该选项生成你的类文件你也可以设置断点和追踪代码 但是你将不能检查变量 (断点是手工指定的程序运行停止的点 ) 即使你使用 g选项编译你的程序也不能调试JAVA平台的核心系统类的局部变量 如果你需要列出某些系统类的局部变量的列表 你需要使用 g选项编译这些类 也就是使用 g选项重新编译rt jar 的类或者是 src zip 里面的文件 然后指定你的 classpath 为正确的类文件使你用新编译的类运行你的程序 在Java 下 使用 boot classpath 选项使得新类被首先加载 记住如果你使用 O 选项优化你的代码 你就不能调试你的类 优化会将所有的调试信息从类中去掉 注意: 检查你的 CLASSPATH 环境变量是正确的才能让调试器和Java 程序知道在哪儿寻找你的类库 你也应该检查你的调试工具看是否需要其它的什么或者是环境变量 设置断点 调试的第一步就是找到代码出错的位置 断点设置能帮你完成这个 断点是你你放置在程序里面的临时标记 它使得调试器知道在哪儿停止程序的执行 例如 如果程序里面的某个申明引发问题 你可以将断点设置在包含那个申明的行上 然后运行程序 在那个申明被执行前程序停止执行 然后你可以检查变量 寄存器 存储器以及堆栈的内容 然后跨过(或执行)那个申明查看问题是怎么引起的 不同的调试器支持不同的断点 一些通用的类型是: 行断点 在程序特定行的代码被执行前被引发 方法断点 在到达被设置成断点的方法时被引发 计数断点 在某个计数器达到或超过某个特定值时被引发 异常断点 在代码抛出一个特定异常时被引发 储存变化断点 在存储在特定地址范围的内容被修改时引发 地址断点 在被设置成断点的地址达到时被引发注意: 一些调试器只在编译版本的Java代码 (使用just in time 编译器生成的代码) 上支持某些断点类型而不支持解释代码(使用javac 工具生成的代码) 一个例子就是地址断点 每个工具在你能设置断点的方式上可能有些不同 检查你的工具的文档 你可能会问 我如何知道在哪儿放置断点? 如果你对这个问题完全没有感觉 你可以在main() 方法的开始设置断点 如果你的代码产生堆栈复写(stack trace) 在程序产生它的地方设置断点 你将在堆栈复写里面看到源代码中出问题的行号 如果你的输出或者图形显示的特定部分没有正确的显示预定信息(例如文本域显示错误的文本) 你可以在该组件被创建的地方设置断点 然后你可以单步执行你的程序显示和GUI对象相关的值 经验将在最合适的地方设置断点 你在一个类或者程序里面可以设置多个断点 通常 你在调试代码的时候会禁止 激活 添加 删除断点 工具会允许你查看你所设置的所有断点的位置同时给你一次删除所有断点的选项 单步执行程序 单步执行程序是最终解决那些棘手的调试问题的方法 它允许你追踪类里面的方法体的整个执行过程 注意 你不需要设置断点就可以停止一个GUI程序的执行 设置断点后在调试器里面开始执行程序 当遇到第一个断点后 你可以越过申明 进入方法体或类体 也可以继续运行直到下一个断点或程序结束 在调试程序的时候经常遇到的术语有 进入 执行当前行 如果当前行包含一个方法调用 执行被调用方法的第一行 如果类中的方法是用不带调试信息的选项编译的 (也就是没有使用 g 选项) lishixinzhi/Article/program/Java/Javascript/201311/25398
深入Java调试体系: 第1部分,JPDA体系概览
JPDA(Java Platform Debugger Architecture)是 Java 平台调试体系结构的缩写 通过 JPDA 提供的 API 开发人员可以方便灵活的搭建 Java 调试应用程序 JPDA 主要由三个部分组成 Java 虚拟机工具接口(JVMTI) Java 调试线协议(JDWP) 以及 Java 调试接口(JDI) 本系列将会详细介绍这三个模块的内部细节 通过实例为读者揭开 JPDA 的面纱 本文是该系列的第一篇 将会着重从整体上介绍 JPDA 的各个组成 阐述它们彼此之间的内在关联
JPDA 概述
所有的程序员都会遇到 bug 对于运行态的错误 我们往往需要一些方法来观察和测试运行态中的环境 在 Java 程序中 最简单的 您是否尝试过使用 System out println() 来输出您的 Java 程序的执行中的各种变量状态来发现您的 Java 程序运行时的问题?这种方式方便易用 在一些简单的情况下能够解决您的问题 但是如果当您的程序运行在远程环境上 或者当前环境不允许控制台终端输出(比如 考虑一下虚拟机初始化之时) 您无法获取终端输出的时候呢?或者 如果您根本无法本地修改运行您的程序?
无须担心 您可以通过很多的调试工具来帮助您解决这个问题 常见的 IDE 都附带一个非常直观简单的调试工具 比如 Eclipse(图 )就提供一个功能非常全面 操作非常简单的调试器
图 使用 Eclipse 调试 Java 程序
其他的一些常见的 Java IDE 比如 Netbeans 和 IntelliJ 等等也都提供了类似的功能 您甚至能不用 IDE 提供的图形界面 使用 JDK 自带的 jdb 工具 以文本命令的形式来调试您的 Java 程序 这些形形 *** 的调试器都支持本地和远程的程序调试 那么它们是如何被开发的?它们之间存在着什么样的联系呢?我们不得不提及 Java 的调试体系—— JPDA
我们知道 Java 程序都是运行在 Java 虚拟机上的 我们要调试 Java 程序 事实上就需要向 Java 虚拟机请求当前运行态的状态 并对虚拟机发出一定的指令 设置一些回调等等 那么 Java 的调试体系 就是虚拟机的一整套用于调试的工具和接口
对于 Java 虚拟机接口熟悉的人来说 您一定还记得 Java 提供了两个接口体系 JVMPI(Java Virtual Machine Profiler Interface)和 JVMDI(Java Virtual Machine Debug Interface) 而它们 以及在 Java SE 中准备代替它们的 JVMTI(Java Virtual Machine Tool Interface) 都是 Java 平台调试体系(Java Platform Debugger Architecture JPDA)的重要组成部分 Java SE 自 版就开始推出 Java 平台调试体系结构(JPDA)工具集 而从 JDK x 开始 Java SDK 就提供了对 Java 平台调试体系结构的直接支持 顾名思义 这个体系为开发人员提供了一整套用于调试 Java 程序的 API 是一套用于开发 Java 调试工具的接口和协议 本质上说 它是我们通向虚拟机 考察虚拟机运行态的一个通道 一套工具 理解这一点对于学习 JPDA 非常重要
换句话说 通过 JPDA 这套接口 我们就可以开发自己的调试工具 通过这些 JPDA 提供的接口和协议 调试器开发人员就能根据特定开发者的需求 扩展定制 Java 调试应用程序 开发出吸引开发人员使用的调试工具 前面我们提到的 IDE 调试工具都是基于 JPDA 体系开发的 区别仅仅在于它们可能提供了不同的图形界面 具有一些不同的自定义功能 另外 我们要注意的是 JPDA 是一套标准 任何的 JDK 实现都必须完成这个标准 因此 通过 JPDA 开发出来的调试工具先天具有跨平台 不依赖虚拟机实现 JDK 版本无关等移植优点 因此大部分的调试工具都是基于这个体系的
JPDA 组成模块
JPDA 定义了一个完整独立的体系 它由三个相对独立的层次共同组成 而且规定了它们三者之间的交互方式 或者说定义了它们通信的接口 这三个层次由低到高分别是 Java 虚拟机工具接口(JVMTI) Java 调试线协议(JDWP)以及 Java 调试接口(JDI) 这三个模块把调试过程分解成几个很自然的概念 调试者(debugger)和被调试者(debuggee) 以及他们中间的通信器 被调试者运行于我们想调试的 Java 虚拟机之上 它可以通过 JVMTI 这个标准接口 监控当前虚拟机的信息 调试者定义了用户可使用的调试接口 通过这些接口 用户可以对被调试虚拟机发送调试命令 同时调试者接受并显示调试结果 在调试者和被调试着之间 调试命令和调试结果 都是通过 JDWP 的通讯协议传输的 所有的命令被封装成 JDWP 命令包 通过传输层发送给被调试者 被调试者接收到 JDWP 命令包后 解析这个命令并转化为 JVMTI 的调用 在被调试者上运行 类似的 JVMTI 的运行结果 被格式化成 JDWP 数据包 发送给调试者并返回给 JDI 调用 而调试器开发人员就是通过 JDI 得到数据 发出指令 图 展示了这个过程
图 JPDA 模块层次
当然 开发人员完全可以不使用完整的三个层次 而是基于其中的某一个层次开发自己的应用 比如您完全可以仅仅依靠通过 JVMTI 函数开发一个调试工具 而不使用 JDWP 和 JDI 只使用自己的通讯和命令接口 当然 除非是有特殊的需求 利用已有的实现会使您事半功倍 避免重复发明轮子
这三个模块我们会在后续文章中分别详细介绍 这里我们简单介绍它们的主要功能
Java 虚拟机工具接口(JVMTI)
JVMTI(Java Virtual Machine Tool Interface)即指 Java 虚拟机工具接口 它是一套由虚拟机直接提供的 native 接口 它处于整个 JPDA 体系的最底层 所有调试功能本质上都需要通过 JVMTI 来提供 通过这些接口 开发人员不仅调试在该虚拟机上运行的 Java 程序 还能查看它们运行的状态 设置回调函数 控制某些环境变量 从而优化程序性能 我们知道 JVMTI 的前身是 JVMDI 和 JVMPI 它们原来分别被用于提供调试 Java 程序以及 Java 程序调节性能的功能 在 J SE 之后 JDK 取代了 JVMDI 和 JVMPI 这两套接口 JVMDI 在最新的 Java SE 中已经不提供支持 而 JVMPI 也计划在 Java SE 后被彻底取代
Java 调试线协议(JDWP)
JDWP(Java Debug Wire Protocol)是一个为 Java 调试而设计的一个通讯交互协议 它定义了调试器和被调试程序之间传递的信息的格式 在 JPDA 体系中 作为前端(front end)的调试者(debugger)进程和后端(back end)的被调试程序(debuggee)进程之间的交互数据的格式就是由 JDWP 来描述的 它详细完整地定义了请求命令 回应数据和错误代码 保证了前端和后端的 JVMTI 和 JDI 的通信通畅 比如在 Sun 公司提供的实现中 它提供了一个名为 jdwp dll(jdwp so)的动态链接库文件 这个动态库文件实现了一个 Agent 它会负责解析前端发出的请求或者命令 并将其转化为 JVMTI 调用 然后将 JVMTI 函数的返回值封装成 JDWP 数据发还给后端
另外 这里需要注意的是 JDWP 本身并不包括传输层的实现 传输层需要独立实现 但是 JDWP 包括了和传输层交互的严格的定义 就是说 JDWP 协议虽然不规定我们是通过 EMS 还是快递运送货物的 但是它规定了我们传送的货物的摆放的方式 在 Sun 公司提供的 JDK 中 在传输层上 它提供了 socket 方式 以及在 Windows 上的 shared memory 方式 当然 传输层本身无非就是本机内进程间通信方式和远端通信方式 用户有兴趣也可以按 JDWP 的标准自己实现
Java 调试接口(JDI)
JDI(Java Debug Interface)是三个模块中最高层的接口 在多数的 JDK 中 它是由 Java 语言实现的 JDI 由针对前端定义的接口组成 通过它 调试工具开发人员就能通过前端虚拟机上的调试器来远程操控后端虚拟机上被调试程序的运行 JDI 不仅能帮助开发人员格式化 JDWP 数据 而且还能为 JDWP 数据传输提供队列 缓存等优化服务 从理论上说 开发人员只需使用 JDWP 和 JVMTI 即可支持跨平台的远程调试 但是直接编写 JDWP 程序费时费力 而且效率不高 因此基于 Java 的 JDI 层的引入 简化了操作 提高了开发人员开发调试程序的效率
表 总结了三个模块的不同点
表 JPDA 层次比较 模块 层次 编程语言 作用 JVMTI 底层 C 获取及控制当前虚拟机状态 JDWP 中介层 C 定义 JVMTI 和 JDI 交互的数据格式 JDI 高层 Java 提供 Java API 来远程控制被调试虚拟机
JPDA 实现
关于 Apache Harmony 项目 Apache Harmony 旨在开发出一个独立且与现有 JDK 兼容的 Java SE 实现 它以 Apache 软件许可证 版发行 它建立了一个开放的模块化运行时架构 包括虚拟机和类库之间及其内部的模块化 通过这个平台 社区能在已有实现的基础上自由定制自己的 Java 实现 或者对某个模块单独进行创新
每一个虚拟机都应该实现 JVMTI 接口 但是 JDWP 和 JDI 本身与虚拟机并非是不可分的 这三个层之间是通过标准所定义的交互的接口和协议联系起来的 因此它们可以被独立替换或取代 但不会影响到整体调试工具的开发和使用 因此 开发和使用自己的 JDWP 和 JDI 接口实现是可能的
Java 软件开发包(SDK)标准版里提供了 JPDA 三个层次的标准实现 事实上 调试工具开发人员还有很多其他开源实现可以选择 比如 Apache Harmony 提供了 JDWP 的实现 而 JDI 我们可以在 Eclipse 一个子项目 eclipse jdt debug 里找到其完整的实现(Harmony 也使用了这套实现 作为其 J SE 类库的一部分) 通过标准协议 Eclipse IDE 的调试工具就可以完全在 Harmony 的环境上运行
Java 调试接口的特点
Java 语言是第一个使用虚拟机概念的流行的编程语言 正是因为虚拟机的存在 使很多事情变得简单而轻松 掌握了虚拟机 就掌握了内存分配 线程管理 即时优化等等运行态 同样的 Java 调试的本质 就是和虚拟机打交道 通过操作虚拟机来达到观察调试我们自己代码的目的 这个特点决定了 Java 调试接口和以前其他编程语言的巨大区别
以C/C++ 的调试为例 目前比较流行的调试工具是 GDB 和微软的 Visual Studio 自带的 debugger 在这种 debugger 中 首先 我们必须编译一个 debug 模式的程序 这个会比实际的 release 模式程序大很多 其次 在调试过程中 debugger 将会深层接入程序的运行 掌握和控制运行态的一些信息 并将这些信息及时返回 这种介入对运行的效率和内存占用都有一定的需求 基于这些需求 这些 Debugger 本身事实上是提供了 或者说 创建和管理了一个运行态 因此他们的程序算法比较复杂 个头都比较大 对于远端的调试 GDB 也没有很好的默认实现 当然 C/C++ 在这方面也没有特别大的需求
而Java 则不同 由于 Java 的运行态已经被虚拟机所很好地管理 因此作为 Java 的 Debugger 无需再自己创造一个可控的运行态 而仅仅需要去操作虚拟机就可以了 Java 的 JPDA 就是一套为调试和优化服务的虚拟机的操作工具 其中 JVMTI 是整合在虚拟机中的接口 JDWP 是一个通讯层 而 JDI 是前端为开发人员准备好的工具和运行库
从构架上说 我们可以把 JPDA 看作成是一个 C/S 体系结构的应用 在这个构架下 我们可以方便地通过网络 在任意的地点调试另外一个虚拟机上的程序 这个就很好地解决了部署和测试的问题 尤其满足解决了很多网络时代中的开发应用的需求 前端和后端的分离 也方便用户开发适合于自己的调试工具
从效率上看 由于 Java 程序本身就是编译成字节码 运行在虚拟机上的 因此调试前后的程序 内存占用都不会有大变化(仅仅是启动一个 JDWP 所需要的内存) 任意程度都可以很好地调试 非常方便 而 JPDA 构架下的几个组成部分 JDWP 和 JDI 都比较小 主要的工作可以让虚拟机自己完成
从灵活性上 Java 调试工具是建立在强大的虚拟机上的 因此 很多前沿的应用 比如动态编译运行 字节码的实时替换等等 都可以通过对虚拟机的改进而得到实现 随着虚拟机技术的逐步发展和深入 各种不同种类 不同应用领域中虚拟机的出现 各种强大的功能的加入 给我们的调试工具也带来很多新的应用
总而言之 一个先天的 可控的运行态给 Java 的调试工作 给 Java 调试接口带来了极大的优势和便利 通过 JPDA 这个标准 我们可以从虚拟机中得到我们所需要的信息 完成我们所希望的操作 更好地开发我们的程序
结束语
lishixinzhi/Article/program/Java/JSP/201311/19143
java程序调试的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java程序调试分析怎么写、java程序调试的信息别忘了在本站进行查找喔。