书名:Java 开发从入门到精通
ISBN:78-7-115-42027-5
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
• 著 扶松柏 陈小玉
责任编辑 张 涛
• 人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
• 读者服务热线:(010)81055410
反盗版热线:(010)81055315
本书由浅入深地详细讲解了Java的开发技术,并通过具体实例的实现过程演练了各个知识点的具体使用流程。本书共20章,第1~2章讲解了Java技术的基础知识,包括Java印象和第一段Java程序;第3~9章分别讲解了Java语法、条件语句、循环语句、数组、面向对象等知识,这些内容都是Java开发技术的核心知识;第10~14章分别讲解了集合、类库、泛型、异常处理、I/O和文件处理的基本知识,这些内容是Java开发技术的重点和难点;第15~19章是典型应用内容,分别讲解了数据库编程、网络与通信编程、多线程等内容;第20章通过一个综合实例的实现过程,介绍了Java技术在综合项目中的使用流程。本书内容循序渐进,以“技术解惑”和“范例演练”贯穿全书,引领读者全面掌握Java语言。
本书不但适用于Java的初学者,也适用于有一定Java基础的读者,还可以作为大专院校相关专业的师生学习用书和培训学校的教材。
从你开始学习编程的那一刻起,就注定了以后所要走的路:从编程学习者开始,依次经历实习生、程序员、软件工程师、架构师、CTO等职位的磨砺;当你站在职位顶峰的位置蓦然回首,会发现自己的成功并不是偶然,在程序员的成长之路上会有不断修改代码、寻找并解决Bug、不停地测试程序和修改项目的经历;不可否认的是,只要你在自己的开发生涯中稳扎稳打,并且善于总结和学习,最终将会得到可喜的收获。
对于一名想从事程序开发的初学者来说,究竟如何学习才能提高自己的开发技术呢?其一的答案就是买一本合适的程序开发图书进行学习。但是,市面上许多面向初学者的编程图书中,大多数篇幅都是基础知识讲解,多偏向于理论,读者读了以后面对实战项目时还是无从下手。讲清如何实现从理论平滑过渡到项目实战的图书,是初学者迫切需要的,为此,作者特意编写了本书。
本书讲解了入门类、范例类和项目实战类三类图书的内容。并且对实战知识不是点到为止地讲解,而是深入地探讨。用纸质书+光盘资料(视频和源程序)+网络答疑的方式,实现了入门+范例练习+项目实战的完美呈现,帮助读者从入门平滑过渡到项目实战的 角色。
为了使读者能够完全看懂本书的内容,本书遵循“入门到精通”基础类图书的写法,循序渐进地讲解这门开发语言的基本知识。
本书采用的不是编程语言知识点的罗列式讲解,为了帮助读者学懂基本知识点,每章都会有“技术解惑”板块,让读者知其然又知其所以然,也就是看得明白,学得通。
书中一共有460个实例,其中有153个正文实例,1个综合实例。每一个正文实例都穿插加入了2个与知识点相关的范例,即全书具有306个拓展范例。通过对这些实例及范例的练习,本书实现了对知识点的横向切入和纵向比较,让读者有更多的实践演练机会,并且可以从不同的角度展现一个知识点的用法,真正实现了举一反三的效果。
书中每一章均提供声、图并茂的语音教学视频,这些视频能够引导初学者快速入门,增强学习的信心,从而快速理解所学知识。
本书根据需要在各章安排了很多“注意”“说明”和“技巧”等小板块,让读者可以在学习过程中更轻松地理解相关知识点及概念,更快地掌握个别技术的应用技巧。
因为本书的内容非常多,不可能用一本书的篇幅囊括“基础+范例+项目案例”的诸多内容,所以,需要配套DVD来辅助实现。在本书的光盘中不但有全书的源代码,而且还有精心制作的实例讲解视频。本书配套的PPT资料可以在网站下载(www.toppr.net)。
本书作者为了方便给读者答疑,特提供了网站论坛、QQ群等技术支持,并且随时在线与读者互动。让大家在互学互帮中形成一个良好的学习编程的氛围。
本书的学习论坛是www.toppr.net。
本书的QQ群是347459801。
本书循序渐进、由浅入深地详细讲解了Java语言开发的技术,并通过具体实例的实现过程演练了各个知识点的具体应用。全书共20章,分别为Java之印象、第一段Java程序、Java语法、条件语句、循环语句、特殊数据——数组、Java的面向对象(上)、Java的面向对象(中)、Java的面向对象(下)、集合、常用的类库、泛型、异常处理、I/O与文件处理、AWT的奇幻世界、Swing详解、数据库编程、网络与通信编程、多线程和综合案例——开发企业快信系统等内容。书中以“技术讲解”“——“范例演练”——“技术解惑”贯穿全书,引领读者全面掌握Java语言开发。
本书的最大特色是实现了入门知识、实例演示、范例演练、技术解惑、综合实战5大部分内容的融合。其中各章内容由如下模块构成。
① 入门知识:循序渐进地讲解了Java语言开发的基本知识点。
② 实例演示:遵循理论加实践的学习模式,用153个实例演示了各个入门知识点的 用法。
③ 范例演练:为了达到对知识点融会贯通、举一反三的效果,每个正文实例配套了2个演练范例,全书共计306个范例,多角度演示了各个知识点的用法和技巧。
④ 技术解惑:把读者容易混淆的部分单独用一个板块进行讲解和剖析,对读者所学的知识实现了“拔高”处理。
下面以本书第3章为例,演示本书各章内容版式的具体结构。
① 入门知识
3.2.5 布尔型
布尔类型是一种表示逻辑值的简单类型,它的值只能是“真”或“假”这两个值中的一个。它是所有的诸如a<b 这样的关系运算的返回类型。Java中的布尔型对应只有一个——boolean类型,用于表示逻辑上的“真”或“假”。boolean类型的值只能是true或false,不能用0或者非0来代表。布尔类型在if、for等控制语句的条件表达式中比较常见,在Java语言中使用boolean型变量的控制流程主要有下面几种。
在下面的内容中,将通过一个简单实例来说明在Java程序中使用布尔类型数据的基本流程。
②实例演示 + ③ 范例演练
实例007 复制布尔型变量并输出结果
源码路径 光盘\daima\3\Bugu.java 视频路径 光盘\视频\实例\第3章\007
实例文件Bugu.java的主要代码如下所示。
public class Bugu //定义类
{
public static void main(String args[])
{
boolean b; //定义b
b = false; //赋值b
System.out.println("b is " + b);
b = true; //赋值b
System.out.println("b is " + b);
if(b) System.out.println("This is executed.");
b = false; //赋值b
if(b) System.out.println("This is not executed.");
System.out.println("10 > 9 is " + (10 > 9));
}
}
范例013:定义两个布尔类型变量并赋值
源码路径:光盘\演练范例\013\
视频路径:光盘\演练范例\013\
范例014:实现强制类型转换
源码路径:光盘\演练范例\014\
视频路径:光盘\演练范例\014\
执行后的效果如图3-6所示。
图3-6 执行效果
④ 技术解惑
3.7 技术解惑
3.7.1 定义常量时的注意事项
3.7.2 char类型中单引号的意义
3.7.3 正无穷和负无穷的问题
3.7.4 移位运算符的限制
初学编程的自学者 编程爱好者
大中专院校的教师和学生 相关培训机构的教师和学员
毕业设计的学生 初、中级程序开发人员
软件测试人员 实习中的初级程序员
在职程序员
十分感谢我的家人给予的巨大支持。本人水平毕竟有限,书中存在纰漏在所难免,诚请读者提出意见或建议,以便修订并使之更臻完善。编辑联系邮箱:zhangtao@ptpress.com.cn。
最后感谢您购买本书,希望本书能成为您编程路上的领航者,祝您阅读快乐!
作者
实例001:定义几个Java常量
范例001:定义并操作常量
范例002:输出错误信息和调试信息
实例002:用变量计算三角形、正方形和长方形的面积
范例003:计算长方形和三角形的面积
范例004:从控制台接受输入字符
实例003:输出设置的变量值
范例005:演示局部变量的影响
范例006:重定向输出流实现程序日志
实例004:输出字符型变量的值
范例007:输出文本字符
范例008:自动类型转换/强制类型转换
实例005:通过整型类型计算正方形和三角形的面积
范例009:演示int类型的提升处理
范例010:自动提升数据类型
实例006:使用浮点型计算圆的面积
范例011:演示不同浮点型的用法
范例012:实现自动类型转换
实例007:复制布尔型变量并输出结果
范例013:定义两个布尔类型变量并赋值
范例014:实现强制类型转换
实例008:使用基本运算符的加减乘除4种运算
范例015:演示基数运算的过程
范例016:实现加密处理
实例009:使用“%”运算符
范例017:演示取模运算的规律
范例018:用三元运算符判断奇偶数
实例010:使用递增递减运算符
范例019:演示递增递减运算符的用法
范例020:更精确地运用浮点数
实例011:使用关系运算符
范例021:演示使用逻辑运算符的用法
范例022:不用乘法运算符实现2x16
实例012:使用条件运算符
范例023:根据条件的不同实现赋值
范例024:实现两个变量的互换
实例013:演示赋值类型不匹配的错误
范例025:扩展赋值运算符的功能
范例026:演示运算符的应用
实例014:使用表达式与运算符
范例027:演示运算符的优先级
范例028:演示关系运算符的应用
实例015:初始化一个字符串
范例029:格式化一个字符串
范例030:扩展赋值运算符的功能
实例016:使用索引方法
范例031:使用追加方法
范例032:货币金额的大写形式
实例017:使用比较字符串方法
范例033:使用求字符串长度方法
范例034:String类格式化当前日期
实例018:使用替换字符串方法
范例035:使用截取字符串方法
范例036:字符串的大小写转换
实例019:将大写字母转换成小写字母
范例037:将小写字母转换成大写字母
范例038:使用trim()方法
实例020:使用追加字符函数
范例039:替换指定的文本字符
范例040:使用颠倒字符方法reverse()
实例021:演示Java的自动转换
范例041:把基本类型转换为字符串
范例042:判断用户名是否正确
实例022:判断成绩是否及格
范例043:检查成绩是否优秀
范例044:判断某一年是否为闰年
实例023:对两种条件给出不同的答案
范例045:根据两种条件给出处理结果
范例046:验证登录信息的合法性
实例024:判断多个条件然后给出不同的值
范例047:判断某年是否是闰年
范例048:为新员工分配部门
实例025:使用switch语句
范例049:使用switch语句
范例050:根据消费金额计算折扣
实例026:在switch语句中去掉break
范例051:去掉break后引发的问题
范例052:判断用户输入月份的季节
实例027:在case语句后没有执行的代码
范例053:判断月份的季节
范例054:判断输入年份是否是闰年
实例028:使用for循环语句输出0-9十个数字
范例055:使用循环遍历数组
范例056:使用for循环输出8个符号
实例029:在屏幕中输出一个用“*”摆放的菱形
范例057:编写一个三角形序列
范例058:使用for循环输入杨辉三角
实例030:循环输出18个数字
范例059:输出累加和不大于30的所有自然数
范例060:使用嵌套循环输出九九乘法表
实例031:使用do-while语句
范例061:使用do-while语句
范例062:计算1+1%2!+1%3!
实例032:在while循环语句中使用break
范例063:在do-while语句中使用break
范例064:循环输出空心的菱形
实例033:使用有标号的break语句
范例065:将break用在嵌套语句中的外层
范例066:演示初学者很容易出现的错误
实例034:使用return语句
范例067:演示return语句的高级用法
范例068:foreach循环优于for循环
实例035:使用continue语句
范例069:使用continue输出小九九
范例070:终止循环体
实例036:创建并输出一维数组中的数据
范例071:将数组Y赋值
范例072:获取一维数组最小值
实例037:初始化一维数组,并将数组值输出打印
范例073:初始化两个不同类型的数组
范例074:将二维数组中的行列互换
实例038:创建二维数组并输出打印里面的数据
范例075:将二维数组的值赋给另外的数组
范例076:利用数组随机抽取幸运观众
实例039:初始化二维数组,然后找到最大数和最小数
范例077:计算二维数组最大值和最小值
范例078:设置JTable表格的列名与列宽
实例040:创建三维数组,然后输出打印数组内元素
范例079:产生一个随机数
范例080:数组的小标和下界
实例041:复制一维数组中的元素
范例081:复制数组元素
范例082:实现计数器界面
实例042:比较两个一维数组
范例083:比较两个数组的元素
范例084:复选框控件数组
实例043:使用foreach遍历数组元素
范例085:演示不对循环变量赋值
范例086:用数组翻转字符串
实例044:在类中创建public的属性和方法
范例087:使用public修饰符
范例088:温度单位转换工具
实例045:使用默认修饰符创建属性和方法
范例089:使用static修饰符
范例090:域的默认初始化值
实例046:演示传递方法的参数
范例091:传递引用类型参数
范例092:编写同名的方法
实例047:在类中创建一个构造方法
范例093:使用构造方法
范例094:构造方法应用
实例048:在类中创建和使用对象
范例095:修改实例048的代码
范例096:使用单例模式
实例049:使用静态变量和静态方法
范例097:在对象中调用静态方法
范例098:祖先的止痒药方
实例050:在类中插入一些特定的包
范例099:插入不同包中的相同类
范例100:统计图书的销售数量
实例051:新建两个类,让其中一个类继承另一个类
范例101:演示类的继承
范例102:不能重写的方法
实例052:用子类去访问父类的构造方法
范例103:自动调用父类中默认的构造方法
范例104:将字符串转换为整数
实例053:用子类去访问父类的属性
范例105:把基本类型转换为字符串
范例106:实现整数进制转换器
实例054:定义一个接口并编写一个抽象方法
范例107:演示子类重写父类的方法
范例108:查看数字的取值范围
实例055:演示方法的重载
范例109:演示Java重载的规则
范例110:ascii编码查看器
实例056:在定义的接口里面编写常量
范例111:演示在接口定义常量出错
范例112:Double类型的比较处理
实例057:编写一个类去实现一个接口
范例113:实现接口继承
范例114:经理和员工的差异
实例058:在类中提供两个同名构造器
范例115:在构造器中使用另一个构造器
范例116:重写父类中的方法
实例059:在类构造器中使用super调用Base构造器里的初始化代码
范例117:演示构造器之间的调用关系
范例118:计算几何图形的面积
实例060:在类中定义一个构造器
范例119:说明初始化块的执行顺序
范例120:提高产品的质量
实例061:把基本类型变量转换成对应包装类对象
范例121:使用自动装箱和自动拆箱
范例122:骑车销售商场模式
实例062:使用final修饰成员变量
范例123:使用final修饰基本类型
范例124:两个相同的宠物
实例063:演示非静态内部类的用法
范例125:使用this限定
范例126:重新计算对象的哈希码
实例064:使用Collection方法操作集合里的元素
范例127:使用Iterator遍历结合元素
范例128:用HashSet删除学生
实例065:使用HashSet判断集合元素相同的标准
范例129:向HashSet添加一个可变对象
范例130:生成一个不重复的随机序列
实例066:演示TreeSet的自然排序用法
范例131:演示TreeSet的定制排序用法
范例132:使用映射的相关类
实例067:使用EnumSet保存枚举类里的值
范例133:复制Collection集合中的元素
范例134:使用集的相关类
实例068:使用List根据索引来操作集合内的元素
范例135:用equals方法判断两个对象是否相等
范例136:通过add方法向List集合中添加元素
实例069:演示LinkedList类的用法
范例137:演示数组的最好性能
范例138:演示PriorityQueue的用法
实例070:使用Collections工具类来操作List集合
范例139:用sort()方法对集合进行排序
范例140:增加所需要的元素
实例071:使用Collections查找处理
范例141:用binarySearch()方法检索内容
范例142:替换一个集合中的指定内容
实例072:通过append连接各种类型的数据
范例143:验证StringBuffer的内容可修改
范例144:实现简单的数字时钟效果
实例073:在任意位置处为StringBuffer添加内容
范例145:演示字符串反转操作
范例146:实现简单的电子时钟效果
实例074:在任意位置处为StringBuffer添加内容
范例147:演示字符串的替换操作
范例148:实现简单的模拟时钟效果
实例075:从StringBuffer中删除指定范围的字符串
范例149:查找指定的内容是否存在
范例150:实现一个简单的万年历
实例076:调用本机可执行程序
范例151:让记事本进程运行5秒后消失
范例152:查看生日的相关信息
实例077:通过ResourceBundle取得资源文件中的内容
范例153:输出不同国家或地区的“你好!”
范例154:判断日期格式的有效性
实例078:使用MessageFormat格式化动态文本
范例155:使用数组传递参数
范例156:使用常见的日期格式
实例079:计算一个程序的执行时间
范例157:列出指定属性
范例158:查看常用的系统属性
实例080:演示DateFormat中的默认操作
范例159:指定显示的风格
范例160:重定向标准输出
实例081:演示格式化日期操作
范例161:将String型数据变为Date型数据
范例162:把一个日期变为指定格式
实例082:演示格式化日期操作
范例163:格式化对象数字
范例164:计算程序运行时间
实例083:使用Integer实例化Comparable接口
范例165:用Comparable操作二叉树
范例166:转换角度和弧度
实例084:验证一个字符串是否是合法的日期格式
范例167:按照字符串的数字拆分字符串
范例168:使用三角函数
实例085:使用String修改之前的操作
范例169:实现字符的替换、验证和拆分
范例170:使用反三角函数
实例086:建立TimerTask的子类,建立测试类进行任务调度
范例171:使用双曲线函数
范例172:指数和对数运算
实例087:如果不检查类型会引发异常
范例173:自定义非泛型栈结构
范例174:用泛型实现栈结构
实例088:创建一个只能存放String对象的StrList集合类
范例175:自定义泛型化数组类
范例176:泛型方法和数据查询
实例089:使用泛型
范例177:泛型化方法和最小值
范例178:泛型化接口和最大值
实例090:定义泛型接口和类
范例179:使用通配符增强泛型
范例180:实现泛型化折半查找
实例091:演示泛型方法的完整用法
范例181:带有两个参数的泛型
范例182:一个有界类型程序
实例092:演示擦除的用法
范例183:使用通配符
范例184:使用泛型方法
实例093:使用try…catch进行捕获并处理
范例185:类没有发现异常
范例186:建立测试类进行任务调度
实例094:处理多个异常
范例187:非法访问异常
范例188:文件未发现异常
实例095:将finally关键字使用在异常中
范例189:数据库操作异常
范例190:在方法中抛出异常
实例096:演示程序如何访问异常信息
范例191:方法上抛出异常
范例192:自定义异常类
实例097:编写一个程序使用throws关键字将异常抛出
范例193:使用throws关键字抛出异常
范例194:捕获单个异常
实例098:使用throw抛出异常
范例195:使用throw关键字处理异常
范例196:捕获多个异常
实例099:在Java程序中使用异常类
范例197:数组下标越界异常
范例198:除零发生异常
实例100:编写自定义异常程序
范例199:深入理解自定义异常
范例200:数组元素类型不匹配异常
实例101:使用File类删除文件
范例201:在删除文件时增加判断
范例202:修改文件的属性
实例102:使用list()方法列出一个目录中的全部内容
范例203:列出目录中全部文件的完整路径
范例204:显示指定类型的文件
实例103:使用RandomAccessFile类写入数据
范例205:使用RandomAccessFile读取数据
范例206:以树结构显示文件的路径
实例104:向文件中写入字符串
范例207:用write(int t)方式写入文件内容
范例208:用FileOutputStream向文件追加内容
实例105:从文件中读取内容
范例209:消除空格
范例210:查找替换文本文件的内容
实例106:使用循环的方式读取文件的内容
范例211:读取指定文件的内容
范例212:批量文件重命名
实例107:将字节输出流变为字符输出流
范例213:将字节输入流变为字符输入流
范例214:快速批量移动文件
实例108:使用PrintStream输出
范例215:进行格式化输出操作
范例216:删除磁盘中的临时文件
实例109:从键盘上读取数据
范例217:没有指定byte数组长度
范例218:动态加载磁盘中的文件
实例110:为System.out输出重定向
范例219:为用户保存错误信息
范例220:重定向输出位置
实例111:输入两个数字,并让两个数字相加
范例221:设计一个专门处理输入数据的类
范例222:删除文件夹中的所有文件
实例112:输入数据
范例223:设计一个分隔符
范例224:创建磁盘索引文件
实例113:实例化ZipFile类对象
范例225:实现压缩处理
范例226:快速全盘查找文件
实例114:取得www.zip中的一个ZipEntry
范例227:读取压缩文件实体
范例228:获取磁盘中所有文件
实例115:修改Person类并实现Externalizable接口
范例229:序列化和反序列化Person对象
范例230:合并多个“.txt”文件
实例116:用Frame创建了一个窗口
范例231:控制窗体加载时的位置
范例232:设置窗体在屏幕中的位置
实例117:使用Panel作为容器盛装了一个文本框和一个按钮
范例233:从上次关闭位置启动窗体
范例234:始终在桌面最顶层显示
实例118:使用ScrollPane容器代替了本节前面的Panel容器
范例235:设置窗体的大小
范例236:根据桌面大小调整窗体大小
实例119:使用FlowLayout布局
范例237:向窗口中分别添加文本框和3个按钮
范例238:禁止改变窗体的大小
实例120:使用BorderLayout布局
范例239:向5个区域中继续添加组件
范例240:设置窗体标题栏的图标
实例121:使用GridLayout布局
范例241:向GridLayout布局区域添加文本框
范例242:拖动没有标题栏的窗体
实例122:使用CardLayout布局
范例243:在窗体中布局各种组件
范例244:设置窗体的背景颜色
实例123:使用BoxLayout布局
范例245:将Box作为容器
范例246:应用流式布局
实例124:演示模式对话框和非模式对话框的用法
范例247:创建打开、保存文件的对话框
范例248:实现一个预览图片复选框
实例125:为文本框编写处理事件
范例249:文本框事件的进一步应用
范例250:实现一个投票计数器软件
实例126:测试了ImageIO所支持读写的全部文件格式
范例251:将图缩小成另一个位图后输出
范例252:实现一个包含图片的弹出菜单
实例127:使用Swing组件创建窗口
范例253:右下角弹出信息窗体
范例254:实现一个淡入淡出窗体
实例128:为Panel容器分别添加几种边框
范例255:实现窗体顶层进度条效果
范例256:设置窗体的鼠标光标效果
实例129:实现“复制”和“粘贴”功能
范例257:在窗体标题显示计时器
范例258:动态地展开窗体
实例130:实现一个颜色选择对话框效果
范例259:实现一个图片查看器
范例260:实现仿QQ隐藏窗体效果
实例131:使用JOptionPane弹出各种对话框
范例261:窗体百叶窗登场特效
范例262:关闭窗体打开网址
实例132:使用JOptionPane弹出各种对话框
范例263:实现nimbus外观
范例264:实现本地系统外观
实例133:实现一个用户可以选择标签布局策略、标签位置的面板
范例265:分割的窗体界面
范例266:圆周运动的窗体
实例134:演示Swing提供的拖放功能
范例267:框架容器的背景图片
范例268:更多选项的框架容器
实例135:演示实现进度条效果的方法
范例269:用SimulatedTarget模拟耗时任务
范例270:拖放的形式改变颜色
实例136:使用SimulatedTarget模拟了一个耗时任务
实例137:使用JSlider创建滑动条
范例271:拦截事件的玻璃窗格
范例272:简单的每日提示信息
实例138:使用JList和JComboBox的构造器创建列表框
范例273:振动效果的提示信息
范例274:网格布局的简单应用
实例139:先绘制好友图像,然后再绘制好友的名字
范例275:可以打开网页的标签
范例276:密码域控件的简单应用
实例140:创建一棵最简单的Swing树
范例277:给文本域设置背景图片
范例278:给文本区设置背景图片
实例141:在树中实现了增加、修改和删除节点功能
范例279:自定义软件安装向导
范例280:查看系统支持的外观
实例141:使用executeUpdate方法创建数据表
范例281:使用insert语句插入记录
范例282:对数据进行降序查询
实例142:使用execute方法执行不同的SQL语句
范例283:对数据进行多条件排序查询
范例284:对统计结果进行排序
实例143:演示InetAddress的简单用法
范例285:普通字符和MIME字符的转换
范例286:获取计算机名和IP地址
实例144:演示InputStream实现多线程下载
范例287:向Web站点发送请求
范例288:获取网址的IP地址
实例145:创建TCP协议的服务器端
范例289:实现TCP协议的客户端
范例290:判断两网址的主机名是否一致
实例146:开发一个聊天室程序
范例291:测试IP判断类型
范例292:查找目标主机
实例147:实现UDP协议的服务器端
范例293:实现UDP协议的客户端
范例294:使用URL访问网页
实例148:用MulticastSocket实现了一个基于广播的多人聊天室
范例295:URL的组成部分
范例296:通过URL获取网页的源码
实例149:在URLConnection中使用代理服务器
范例297:实现一对多通信模式
范例298:自制一个浏览器
实例150:通过改变系统属性来改变默认代理服务器
范例299:扫描TCP端口
范例300:TCP服务器
实例151:使用Thread创建线程
范例301:使用Runnable接口创建线程
范例302:新建无返回值的线程
实例152:演示线程的死亡
范例303:查看线程的运行状态
范例304:查看jvm中的线程名
实例153:演示Java的自动转换
范例305:把基本类型转换为字符串
范例306:查看和修改线程名称
综合实例:整合开发企业快信系统
究竟Java是什么呢?为什么让你在众多语言中选择并学习这门语言呢?本章将会为读者讲解这些疑惑。学完本章的内容,相信初学者会对Java有一个深刻的印象。
知识点讲解:光盘:视频\PPT讲解(知识点)\第1章\初步认识Java.mp4
纵观各大主流招聘媒体,总是会看到多条招聘Java程序员的广告。由此可以看出,Java程序员很受市场欢迎。在本节将带领大家认识Java这门语言,为读者步入本书后面知识的学习打下基础。
Java是由Sun公司于1995年5月推出的Java程序设计语言(以下简称Java语言)和Java平台的总称。用Java实现的HotJava浏览器(支持Java Applet)向我们展示了Java语言的魅力:跨平台、动态的Web、Internet计算。从那以后,Java便被广大程序员和企业用户广泛接受,成为了受欢迎的编程语言之一。
Java平台由Java虚拟机(Java Virtual Machine)和Java应用编程接口(Application Programming Interface,API)构成。Java应用编程接口为Java应用提供了一个独立于操作系统的标准接口,可分为基本部分和扩展部分。在硬件或操作系统平台上安装一个Java平台之后,Java应用程序就可运行。现在,Java平台已经嵌入到了几乎所有的操作系统。这样Java程序只需编译一次,就可以在各种系统中运行。
Java分为如下3个体系。
在Java语言中有许多专业术语,这些专业术语通常是指Java语言下的一个技术或者一个功能,下面介绍一些常用的技术名词。
JDBC(Java DataBase Connectivity)提供连接各种关系数据库的统一接口,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC为数据库开发人员提供了一个标准的API,使数据库开发人员能够用纯 Java API编写数据库应用程序。
EJB(Enterprise JavaBeans)使得程序员可以方便地创建、部署和管理跨平台的基于组件的企业应用。
Java RMI(Java Remote Method Invocation)用来开发分布式Java应用程序。一个Java对象的方法能被远程Java虚拟机调用,这样可以在对等的两端激活远程方法,这也可以发生在客户端和服务器之间,只要双方的应用程序都是用Java编写的。
Java IDL(Java Interface Definition Language)提供了与CORBA(Common Object Request Broker Architecture)的无缝互操作性,这使得Java能集成异构的商务信息资源。
JNDI(Java Naming and Directory Interface)提供了从Java平台到应用程序的统一无缝连接,这个接口屏蔽了企业网络所使用的各种命名和目录服务。
JMAPI(Java Management API)为异构网络上系统、网络和服务管理的开发提供一整套丰富的对象和方法。
JMS(Java Message Service)提供了企业消息服务,例如,可靠的消息队列、发布和订阅通信,以及有关推拉(Push/Pull)技术的各个方面。
JTS(Java Transaction Service)提供了存取事务处理资源的开放标准,这些事务处理资源包括事务处理应用程序和事务处理管理及监控等。
在Java技术中,除了上面的内容,还需要特别关注JavaBeans技术,它是一个开放的、标准的组件体系结构,它虽然独立于平台,但是,使用Java语言开发。
知识点讲解:光盘:视频\PPT讲解(知识点)\第1章\面向对象.mp4
在具体学习Java语言之前,需要先弄清楚什么是面向对象,面向对象思想是学好Java语言的前提。在讲解Java语言的具体语法知识之前,先和大家一起学习面向对象的基本知识。
在目前的软件开发领域有两种主流的开发方法,分别是结构化开发方法和面向对象开发方法。早期的编程语言如C、Basic、Pascal等都是结构化编程语言,随着软件开发技术的逐渐发展,人们发现面向对象可以提供更好的可重用性、可扩展性和可维护性,于是催生了大量的面向对象的编程语言,如C++、Java、C#和Ruby等。
面向对象程序设计即OOP,是Object-Oriented Programming的缩写。面向对象编程技术是一种起源于20世纪60年代的Simula语言,其自身理论已经十分完善,并被多种面向对象程序设计语言(Object-Oriented Programming Langunianling,OOPL)实现。由于很多原因,国内大部分程序设计人员并没有很深的OOP以及OOPL理论,很多人从一开始学习到工作很多年都只是接触到C/C++、Java等静态类型语言,而对纯粹的OOP思想以及动态类型语言知之甚少。
对象的产生通常基于两种基本方式,分别是以原型对象为基础产生新对象和以类为基础产生新对象。
原型模型是以一个有代表性的对象为基础来产生各种新的对象,并由此继续产生更符合实际应用的对象。而原型—委托也是OOP中的对象抽象,是代码共享机制中的一种。
一个类提供了一个或多个对象的通用性描叙。从形式化的观点看,类与类型有关,因此,一个类相当于是从该类中产生的实例的集合。
面向对象编程方法学是Java编程的指导思想。在使用Java进行编程时,应该首先利用对象建模技术(OMT)来分析目标问题,抽象出相关对象的共性,对它们进行分类,并分析各类之间的关系;然后再用类来描述同一类对象,归纳出类之间的关系。Coad和Yourdon在对象建模技术、面向对象编程和知识库系统的基础之上设计了一整套面向对象的方法,具体来说分为面向对象分析(OOA)和面向对象设计(OOD)。对象建模技术、面向对象分析和面向对象设计共同构成了系统设计的过程,如图1-1所示。
图1-1 系统设计处理流程
在进行对象建模、面向对象分析和设计的过程中,需要使用建模语言来描述分析的过程和结果。统一建模语言即UML,是Unified Modeling Langunianling的缩写。UML是为了实现上述目标而设计的一种标准通用的设计语言。
UML为我们提供了多种类型的模型描述图,当在某种给定的方法学中使用这些图时,人们就能更容易理解和交流设计思想。UML图可以分为如下3种类型。
(1)静态图。
静态图即Static Diagram,其功能是描述了不发生任何变化的软件元素的逻辑结构,描绘了类、对象和数据结构及其存在于它们之间的关系。
(2)动态图。
动态图即Dynamic Diagram,其功能是展示软件实体在运行期间的的变化,主要描绘了执行流程、实体改变状态的方式。
(3)物理图。
物理图即Physical Diagram,其功能是显示软件实体不变化的物理结构,主要用来描绘库文件、字节文件和数据文件等,以及存在于它们之间的相互关系。
在Java中,通常使用类图和对象图来表示项目内程序类的结构和各元素间的对应关系。在下面的内容中,将简要介绍类图和对象图的基本知识。
(1)类图。
类图表示不同的实体间的相互关系,显示了系统的静态结构。类图可用于表示逻辑类,逻辑类通常是指事物的种类,比如球队、电影之类的抽象描述。类图还可以用于表示实现类,实现类就是程序员要编写的类。实现类图与逻辑类图可能会用来描述一些相同的类。然而,实现类图与逻辑类图不会使用相同的描述属性。
类图通常用矩形表示,并在矩形内将类分为3个部分。其中最上面的部分显示类的名称,中间部分显示类的属性,最下面的部分显示类的方法,例如图1-2所示的格式。
图1-2 典型类图结构
注意:在现实应用中,最常用、最简单的类图就是一个在里面显示了类名的长方形。在大多数的UML中,多数类只要有一个能够清楚表达的命名就可以了。
在类名部分还可以显示类的构造类型,类的构造型在双角括符号“« »”之间指定,并放在类的名称上面。常见的构造类型包括如下3类。
如果类名用斜体表示,或者在类名下面,则表示这个类是一个抽象类。
在属性和方法的前面可以用修饰符“+”或“-”,其功能是表示属性或方法的作用域,具体说明如下所示。
通常在类的属性或方法参数名称的冒号后,显示了属性的类型或方法的参数的类型。方法的返回值类型显示在方法后面的冒号之后。
例如图1-3显示了一个Lei类的类图结构。
图1-3 Lei类的类图结构
(2)对象图。
对象图的功能是用来表示类的实例化对象。通常用一个两层的矩形结构来表示对象图,其中上层标识对象名和类名,下层标识对象的实例化属性值。例如在下面的代码中,创建了一个Lei类的对象mm。
Lei mm = new Lei("mm", 'F', 24);
上述mm对象的对象图如图1-4所示。
图1-4 对象图示例
在同一个应用项目中,类之间可能存在如下多种类别的相互关系。
UML是一种设计语言,它的目的不是表现细节,而是表现结构,仅仅展示必要的细节。所以UML不可能与源代码一一对应,只是在结构上存在了某种对应关系。
除了前面介绍的类图和对象图外,在Java中还可以使用序列图和状态图来表示项目内程序类的结构和各元素间的对应关系。在下面的内容中,将对序列图和状态图的基本知识进行简要介绍。
(1)序列图。
序列图显示具体用例(或用例的一部分)的详细流程,它不但显示了流程中不同对象之间的交互关系,而且还可以很详细地显示对不同对象的各种调用。在序列图中有如下两个维度。
对象之间的交互存在如下5种关系。
绘制序列图的方法非常简单,通常用图顶部的框表示类的实例对象,框中的类实例名称和类名称之间用空格/冒号/空格来分隔。如果某个类实例向另一个类实例发送了处理消息,则绘制一条具有指向接收类实例的开箭头的连线,并把处理的名称放在连线上面。对于某些特别重要的消息,可以绘制一条具有指向发起类实例的开箭头的虚线,将返回值标注在虚线上。有助于序列图的阅读。
(2)状态图。
状态图表示某个类所处的不同状态和该类的状态转换信息。每个类都有状态,但不是每个类都应该有一个状态图。只有当行为的改变和状态有关时才创建状态图。一般只描述在系统活动期间具有3个或更多潜在状态的类的状态图。
状态图中的符号集包括如下5个基本元素。
在绘制状态图时,首先需要绘制起点和一条指向该类的初始状态的转换线段。状态本身可以在图上的任意位置绘制,然后只需使用状态转换线条将它们连接起来。
对象建模技术源于通用电气公司的一套系统开发技术,是以面向对象的思想为基础,通过对问题进行抽象而构造出一组相关的模型。通过对象建模技术,可以全面地描述问题领域的结构。对象建模技术把分析时收集到的信息构造在如下3类模型中。
通过上述3个模型,可以从不同的角度对系统进行描述,首先分别着重于系统的某个侧面,然后整体组合起来构成对系统的完整描述。
功能模型的功能是实现系统内部数据的传送和处理。功能模型能够说明,从输入数据能够计算出什么样的输出数据,但是,没有考虑参加计算的数据按什么时序来执行。功能模型由多个数据流图组成,它们指明从外部输入,通过操作和内部存储,直到外部输出的整个数据流情况。功能模型还包括了对象模型内部数据间的限制。功能模型中的数据流图往往形成一个层次结构,一个数据流图的过程可以由下一层的数据流图作进一步的说明。UML中通常使用用例图和活动图来描述功能模型。
建立功能模型的主要步骤如下所示。
(1)确定输入和输出值。
(2)用数据流图表示功能的依赖性。
(3)具体说明每个具体功能。
(4)确定限制。
(5)确定功能优化的准则。
上述操作的具体实现流程如图1-5所示。
图1-5 功能模型处理流程
对象模型的功能是描述系统的静态结构,包括类和对象,它们的属性和操作,以及它们之间的关系。构造对象模型的主要目的是,发掘与项目应用密切相关的概念。对象模型用包含对象和对象之间关系的图来表示,在UML中通常使用类图和对象图来描述对象模型。
使用OMT建立对象模型的主要步骤如下所示。
(1)确定对象类。
(2)定义数据词典,并利用它来描述类的属性和类之间的关系。
(3)用继承来组织和简化类的结构和类之间的关系。
(4)测试访问路径。
(5)根据对象之间的关系和对象的功能将对象分组建立模块。
上述操作的具体实现流程如图1-6所示。
图1-6 对象模型处理流程
动态模型主要用于控制系统的逻辑,考察在任何时候对象及其关系的改变,描述这些涉及时序和改变的状态。通常使用状态图和事件跟踪图来描述动态模型。
状态图是状态和事件以及它们之间的关系所形成的网络,侧重于描述每一类对象的动态行为。而事件跟踪图则侧重于说明系统执行过程中的一个特点场景,描述完成系统某个功能的一个事件序列。
对象到对象的单个消息叫做一个事件。在系统的一个特定环境下发生的一系列事件叫做一个场景。场景通常起始于一个系统外部的输入事件,结束于一个系统外部的输出事件。在一个场景中,一系列事件和交换事件的对象都可以放在一个事件跟踪图中表示。UML使用状态图和序列图来描述动态模型,序列图对应于事件跟踪图。
建立动态模型的主要步骤如下所示。
(1)预制典型的交互序列场景。
(2)确定对象之间的事件,为每个场景建立事件跟踪图。
(3)为每个系统预制一个事件流图。
(4)为具有重要动态行为的类建立状态图。
(5)检验不同状态图中共享的事件的一致性和完整性。
上述操作的具体实现流程如图1-7所示。
图1-7 动态模型处理流程
面向对象分析属于软件开发过程中的问题定义阶段。传统的系统分析产生一组面向过程的文档,定义目标系统的功能;面向对象分析则产生一种描述系统功能和问题领域的基本特征的综合文档。
Java中面向对象的分析需要遵循下面的原则。
(1)抽象。
从许多事物中舍弃个别的、非本质的特征,抽取共同的、本质性的特征,这就是抽象。抽象是形成概念的必要手段。抽象原则具有如下两点意义。
抽象是面向对象方法中使用最为广泛的原则,抽象原则包括过程抽象和数据抽象两个方面。
(2)封装。
封装就是把对象的属性和服务结合为一个不可分的系统单位,并尽可能隐蔽对象的内部细节。
(3)继承。
特殊类的对象拥有的其一般类的全部属性与服务,这是特殊类对一般类的继承。在面向对象分析中运用继承原则,就是在每个由一般类和特殊类形成的结构中,把一般类的对象实例和所有特殊类的对象实例都共同具有的属性和服务,一次性地在一般类中进行显式定义。在特殊类中不再重复地定义一般类中已定义的东西,但是在语义上,特殊类却自动地、隐含地拥有它的一般类(以及所有更上层的一般类)中定义的全部属性和服务。继承原则的好处是:使系统模型比较清晰。
(4)分类。
分类就是把具有相同属性和服务的对象划分为一类,用类作为这些对象的抽象描述。分类原则实际上是抽象原则运用于对象描述时的一种表现形式。
(5)聚合。
聚合的原则是:把一个复杂的事物看成若干比较简单的事物的组装体,从而简化对复杂事物的描述。
(6)关联。
通过一个事物联想到另外的事物,能使人发生联想的原因是事物之间确实存在着某些联系。
(7)消息通信。
这一原则要求对象之间只能通过消息进行通信,而不允许在对象之外直接地存取对象内部的属性。通过消息进行通信是由于封装原则引起的。在OOA中要求用消息连接表示出对象之间的动态联系。
(8)粒度控制。
考虑某部分的细节时暂时撇开其余的部分,这就是粒度控制原则。
面向对象分析的过程分为两个阶段,分别是问题领域分析和应用分析,这两个阶段的具体说明如下所示。
(1)问题领域分析阶段。
问题领域分析是软件开发的基本组成部分,目的是使开发人员了解问题领域的结构,建立大致的系统实现环境。问题领域分析给出一组抽象概念作为特定系统需求开发的参考。问题领域分析实际上是一种学习过程。软件开发人员在这个阶段应该尽可能地理解当前系统中与应用有关的知识,放宽考虑的范围,尽可能地标识与应用有关的概念。有了广泛的问题领域知识,涉及具体的应用时,就可以更快地进入状态,掌握应用的核心知识。而且,在用户改变对目标系统的需求时,广泛的分析可以帮助我们预测出目标系统在哪些方面会发生哪些变化。在分析过程中,应该标识出系统的基本概念(对象、类、方法、关系等)、识别问题领域的特征,并把这些概念集成到问题领域的模型中。问题领域的模型必须包含概念之间的关系,以及每个概念的全部信息。标识出来的相关概念应该根据信息内容来有机地融合到问题领域的综合视图中。
(2)应用分析阶段。
应用分析是依据在问题领域分析时建立起来的问题领域模型来进行的。应用分析时,把问题领域模型用于当前特定的应用之中。首先,通过收集到的用户信息来对问题领域进行取舍,把用户需求作为限制条件来使用,以缩减问题领域的信息量。因此,问题领域分析的视野大小直接影响到应用分析保留的信息量。一般来说,问题领域分析阶段产生的模型并不需要用程序设计语言来表示,而应用分析阶段产生的影响条件则需要用某种程序设计语言来表示。模型识别的要求可以针对一个应用,也可以针对多个应用。通常我们着重考虑两个方面,即应用视图和类视图。在类视图中,必须对每个类的属性和操作进行细化,并表示出类之间的相互作用关系。
面向对象分析需要完成如下两个目标。
(1)形式化地说明所面对的应用问题,最终形成软件系统基本构成的对象,以及系统所必须遵从的、由应用环境所决定的规则和约束条件。
(2)明确地规定构成系统的对象如何协同工作和完成指定的功能。
通过面向对象分析所建立的系统模型是以概念为中心的,因此称为概念模型。概念模型由一组相关的类组成。面向对象分析可以通过自顶向下地逐层分解来建立系统模型,也可以自底向上地从已经定义的类出发,逐步构造新的类。
概念模型的构造和评审由如下5个层次构成。
上述5个层次不是构成软件系统的层次,而是分析过程中的层次。当5个层次的工作全部完成时,面向对象分析的任务也就完成了。
注意:在实际编程操作中,面向对象分析的目标是得出问题领域的功能模型、对象模型和动态模型,并用相应的UML图将它们表示出来。
经过前面的分析处理后,接下来就可以进行具体设计了。面向对象设计的任务是对面向对象分析的结果进行规范化整理,以便能够被面向对象编程直接接受。在接下来的内容中,将简要介绍面向对象设计的基本知识。
面向对象设计是一种软件设计方法,是一种工程化规范。面向对象设计中主要的操作如下所示。
所以说,面向对象设计就是一个根据需求决定所需的类、类的操作,以及类之间关联的过程。
从面向对象分析到面向对象设计是一个逐步扩充模型的过程。面向对象分析以实际问题为中心,可以不考虑与软件实现相关的任何问题,主要考虑“做什么”的问题;面向对象设计则是面向软件实现的实际开发活动,主要考虑“怎么做”的问题。
面向对象设计的目标是管理程序内部各部分的相互依赖关系。为了达到这个目标,面向对象设计要求将程序分成块,然后分别将各个块隐藏在接口(interface)的后面,让它们只通过接口相互交流。比如说,如果用面向对象设计的方法来设计一个客户端—服务器应用,那么服务器和客户端之间不应该有直接的依赖,而是应该让服务器的接口和客户端的接口相互依赖。
面向对象设计所要遵循的原则如下所示。
(1)模块化。
面向对象开发方法很自然地支持了把系统分解成模块的设计原则:对象就是模块。它是把数据结构和操作这些数据的方法紧密地结合在一起所构成的模块。
(2)抽象。
面向对象方法不仅支持过程抽象,而且支持数据抽象。
(3)信息隐藏。
在面向对象方法中,信息隐藏通过对象的封装性来实现。
(4)低联系。
在面向对象方法中,对象是最基本的模块,因此,联系主要指不同对象之间相互关联的紧密程度。低联系是设计的一个重要标准,因为这有助于使得系统中某一部分的变化对其他部分的影响降到最低。
面向对象设计有如下3个任务。
(1)对象定义规格的求精。
对于面向对象分析所抽象出来的对象、类,以及汇集的分析文档,面向对象设计需要有一个根据设计要求整理和求精的过程,使之更能符合面向对象编程的需要,具体实施如下。
(2)数据模型和数据库设计。
数据模型的设计需要确定类、对象属性的内容、消息连接的方式、系统访问、数据模型的方法等。最后,每个对象实例的数据都必须落实到面向对象的库结构模型中。
(3)优化。
面向对象设计的优化设计过程是从另一个角度对分析结果和处理业务过程的整理归纳,优化包括对象和结构的优化、抽象、集成。
面向对象设计的过程,是通过利用设计阶段中的4个层次来建立系统的问题领域、用户界面、任务管理和数据管理的过程。
(1)问题领域。
问题领域包括与我们所面对的应用问题直接相关的所有类和对象。主要是根据需求的变化来对面向对象分析阶段产生的模型中的类和对象、结构、属性和操作进行组合和分解,根据面向对象设计原则来增加必要的类、属性和关系。
(2)用户界面。
通常在面向对象分析阶段给出了所需的属性和操作,在面向对象设计阶段必须根据需求把交互的细节加入用户界面的设计中,包括有效的人机交互所必需的实际显示和输入。
用户界面部分的设计主要由以下7个方面组成:
(3)任务管理。
任务是进程的别称,是执行一系列活动的一段程序。当系统中有许多并发行为时,需要依照各个行为的协调和通信关系来划分各种任务,以简化并发行为的设计和编码。任务管理主要包括任务的选择和调整。
(4)数据管理。
数据管理提供了在数据管理系统中存储和检索对象的基本结构,包括对永久性数据的访问和管理。数据管理的方法主要有3种,分别是文件管理、关系数据库管理,以及面向对象的数据库管理。
Java是一门纯粹的面向对象的编程语言,完全支持封装、继承和多态这三大面向对象的基本特征。Java程序的组成单位就是类,不管什么规模的Java应用程序,都是由一个个类组成的。
在Java语言中,除了8个基本数据类型值之外都是对象,对象就是面向对象程序设计的中心。对象是人们要进行研究的任何事物,从最简单的数字到复杂的航空母舰等均是对象。对象不仅能表示具体的事物,而且还能表示抽象的规则、计划或事件。对象是具有状态的,一个对象用数据值来描述它的状态。Java通过为对象定义Field(以前常被称为属性,现在也称为字段)来描述对象的状态。对象也具有操作,这些操作可以改变对象的状态,对象的操作也被称为对象的行为,Java通过为对象定义方法来描述对象的行为。对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中。对象是Java程序里的核心,所以,Java里的对象具有唯一性,每个对象都有一个标识来引用它,如果某个对象失去了标识,这个对象将变成垃圾,只能等着系统垃圾回收来回收它。Java语言不允许直接访问对象,而是通过对对象的引用来操作对象。
具有相同或相似性质的一组对象的抽象就是类,类是抽象的、概念上的定义,是对一类事物的描述。对象是实际存在的该类事物的每个个体,因而也称实例(instance)。对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象。类用来描述一系列对象,类会概述每个对象应包括的数据,类概述每个对象的行为特征。因此,我们可以把类理解成某种概念、定义,它规定了某类对象所共同具有的数据和行为特征。
Java语言使用关键字class来定义一个类,Java允许程序员自定义类。在Java中定义类时,可使用关键字Field来描述该类对象的数据,可使用方法来描述该类对象的行为特征。类的行为特主要是指属性和操作,具体说明如下所示。
在客观世界中有若干类,这些类之间有一定的结构关系。通常有如下两种主要的结构关系。
程序员在定义Java类之后,就可以使用关键字new来创建指定类的对象,每个类可以创建任意多个对象,多个对象的Field值可以不同,这表现为不同对象的数据存在差异。
Java语言开发技术博大精深,能够应用于多个领域。正是因为如此,一直深受广大程序员的喜爱。作为一名初学者,肯定会在学习过程中遇到很多疑问和困惑。在本节的内容中,笔者将自己的心得体会告诉大家,帮助读者解答困惑问题。
面向对象之父Alan Kay曾经总结了第一个成功的面向对象语言的5个基本特性,这同时也是Java语言所具备的5个基本特性,这些特性表现了一种纯粹的面向对象程序设计方式。
(1)万物皆为对象。将对象视为奇特的变量,它可以存储数据,除此之外,你还可以要求它在自身上执行操作。
(2)程序是对象的集合,它们通过发送消息来告知彼此所要做的。要想请求一个对象,就必须对该对象发送一条消息。也就是说,可以把消息想像为对某个特定对象的方法的调用请求。
(3)每个对象都有自己的由其他对象所构成的存储。换句话说,可以通过创建包含现有对象的包的方式来创建新类型的对象。因此,可以在程序中构建复杂的体系,同时将其复杂性隐藏在对象的简单性背后。
(4)每个对象都拥有其类型,在Java程序中,需要将每个对象都表示成某个类(class)的一个实例(instance),这里“类”就是“类型”的同义词。每个类区别于其他类的特性就是“可以发送什么样的消息给它”。
(5)某一特定类型的所有对象都可以接收同样的消息。例如“圆形”类型的对象同时也是“几何形”类型的对象,所以,一个“圆形”对象必定能够接收发送给“几何形”对象的消息。这意味着可以编写与“几何形”交互并自动处理所有与几何形性质相关的事物的代码。这种可替代性(substitutability)是OOP中最强有力的概念之一。
另一位名叫Booch的大师针对对象提出了一个更加简洁的描述:对象具有状态、行为和标识。这意味着每一个对象都可以拥有内部数据(它们给出了该对象的状态)和方法(它们产生行为),并且每一个对象都可以唯一地与其他对象区分开来,具体说来,就是每一个对象在内存中都有一个唯一的地址。
(1)学得要深入,基础要扎实。
基础的作用不必多说,在大学课堂上曾经讲过了很多次,在此重点说明“深入”。职场不是学校,企业要求你能高效地完成项目功能,但是现实中的项目种类繁多,我们需要从基础上掌握Java技术的精髓。走马观花式的学习已经被社会所淘汰,入门水平不会被开发公司所接受,他们需要的是高手。
(2)恒心,演练,举一反三。
学习编程的过程是枯燥的,我们需要将学习Java当成是自己的乐趣,只有做到持之以恒才能有机会学好。另外,编程最注重实践,最害怕闭门造车。每一个语法,每一个知识点,都要反复用实例来演练,这样才能加深对知识的理解。要做到举一反三,只有这样才能对知识有深入的理解。
在Java的众多突出特性之中,垃圾回收机制是它最具代表性的一个。在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其他对象;而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾,JVM的一个系统级线程会自动释放该内存块,垃圾收集意味着程序不再需要的对象是“无用信息”,这些信息将被丢弃。当一个对象不再被引用时,内存回收它占领的空间,以便空间被后来的新对象使用。事实上,除了释放没用的对象,垃圾收集也可以清除内存记录碎片。由于创建对象和垃圾收集器释放丢弃对象所占的内存空间,因此,内存会出现碎片。碎片是分配给对象的内存块之间的空闲内存洞。碎片整理将所占用的堆内存移到堆的一端,JVM将整理出的内存分配给新的对象。
垃圾收集能自动释放内存空间,减轻编程的负担,这使Java虚拟机具有一些优点。首先,它能使编程效率提高。在没有垃圾收集机制的时候,可能要花许多时间来解决一个难懂的存储器问题。在用Java语言编程时,靠垃圾收集机制可大大缩短时间。另外,它保护程序的完整性,垃圾收集是Java语言安全性策略的一个重要部分。
垃圾收集的一个潜在的缺点是它的开销影响程序性能。Java虚拟机必须追踪运行程序中有用的对象,而且最终释放没用的对象。这一个过程需要花费处理器的时间。另外,垃圾收集算法的不完备性,使得早先采用的某些垃圾收集算法不能保证100%收集到所有的废弃内存。当然,随着垃圾收集算法的不断改进以及软、硬件运行效率的不断提升,这些问题都可以得到解决。
经过本书第1章内容的学习,已经了解了Java语言的基本特点,并且对面向对象编程思想有了一个大体了解。从本章开始,将和大家一起来学习Java语言的基本知识。在学习具体语法知识之前,首先讲解搭建Java开发环境的方法,并通过一段程序来介绍Java的运作机制,为步入本书后面知识的学习打下基础。
知识点讲解:光盘:视频\PPT讲解(知识点)\第2章\搭建Java开发平台.mp4
“工欲善其事,必先利其器”,这一说法在编程领域同样行得通,因为学习Java开发也离不开一款好的开发工具。但是在使用开发工具进行Java开发之前,需要先安装JDK并进行相关设置。
我们必须先安装JDK,然后再配置环境,只有这样才能够在自己的计算机系统中编译并运行一个Java程序。JDK(Java Development Kit)是整个Java的核心,包括了Java运行环境、Java工具和Java基础的类库。JDK是学好Java的第一步,是开发和运行Java环境的基础,当用户要对Java程序进行编译的时候,必须先获得对应操作系统的JDK,否则将无法编译Java程序。在安装JDK之前需要先获得JDK,获得JDK的具体操作如下。
(1)在Sun官方网站下载,网址为http://developers.sun.com/downloads/,如图2-1所示。
图2-1 Sun官方下载页面
(2)在图2-1中可以看到有很多版本,在此选择当前最新的Java 7,其下载页面如图2-2所示。
图2-2 JDK下载页面
(3)在图2-2中单击JDK下方的“Download”按钮,在弹出的新界面中选择我们所要下载的JDK,例如笔者选择的是Windows x86版本,如图2-3所示。
图2-3 选择Windows x86版本
(4)下载完成后双击下载的“.exe”文件开始进行安装,将弹出“安装向导”对话框,在此单击“下一步”按钮,如图2-4所示。
图2-4 “安装向导”对话框
(5)弹出“安装路径”对话框,在此选择文件的安装路径,如图2-5所示。
图2-5 “安装路径”对话框
(6)设置好安装路径,然后单击“下一步”按钮开始在安装路径下解压缩下载的文件,如图2-6所示。
图2-6 解压缩下载的文件
(7)完成后弹出“目标文件夹”对话框,在此选择要安装的位置,如图2-7所示。
图2-7 “目标文件夹”对话框
(8)单击“下一步”按钮后开始正式安装,如图2-8所示。
图2-8 继续安装
(9)完成后弹出“完成”对话框,单击“完成”按钮完成整个安装过程,如图2-9所示。
图2-9 完成安装
完成安装后可以检测是否安装成功,检测方法是依次单击“开始”︱“运行”,在运行框中输入“cmd”并按下回车键,在打开的CMD窗口中输入java –version,如果显示如图2-10所示的提示信息,则说明安装成功。
图2-10 CMD窗口
如果上面的安装失败也没有关系,我们只需将其目录的绝对路径添加到系统的PATH中即可解决。下面就为大家奉上该解决办法的流程。
(1)右键依次单击“我的电脑”︱“属性”︱“高级”,单击下面的“环境变量”,在下面的“系统变量”处选择新建,在变量名处输入JAVA_HOME,在变量值中输入刚才的目录,比如笔者使用的“E:\jdk1.7.0_01”,如图2-11所示。
图2-11 设置系统变量
(2)再次新建一个变量名为classpath,其变量值如下所示。
.;%JAVA_HOME%/lib/rt.jar;%JAVA_HOME%/lib/tools.jar
单击“确定”按钮找到PATH的变量,双击或单击编辑,在变量值最前面添加如下值。
%JAVA_HOME%/bin;
具体如图2-12所示。
图2-12 设置系统变量
(3)再依次单击“开始”︱“运行”,在运行框中输入“cmd”并按下回车键,在打开的CMD窗口中输入java –version,如果显示如图2-13所示的提示信息,则说明安装成功。
图2-13 CMD界面
注意:上述变量设置中,是按照笔者本人的安装路径设置的,笔者安装JDK的路径是C:\Program Files\Java\jdk1.7.01_b08。
知识点讲解:光盘:视频\PPT讲解(知识点)\第2章\编写第一段Java程序.mp4
当完成Java开发环境的安装工作后,接下来开始编写一段Java程序,并把这段Java程序进行编译运行,正式开始我们的编码之旅。
打开记事本,在记事本里编写下面的代码。
public class First{
/*这是一个 main 方法*/
public static void main(String [] args){
/* 输出此消息 */
System.out.println("第一段Java程序!");
}
}
然后记事本文件保存为first.java,如图2-14所示。
图2-14 记事本文件first.java
注意:可以编写Java程序的编辑器
我们可以使用任何无格式的文本编辑器来编辑Java源代码,在Windows操作系统上可以使用记事本(NotePad)、EditPlus等程序,在Linux平台上可使用vi命令等。但是不能使用写字板和Word等文档编辑器来编写Java程序。因为写字板和Word等工具是有格式的编辑器,当我们使用它们编辑一份文档时,这个文档中会包含一些隐藏的格式化字符,这些隐藏字符会导致程序无法正常编译和运行。
我们需要使用javac命令来编译Java程序,由于前面已经把javac命令所在的路径添加到了系统的PATH环境变量中,因此现在可以使用javac命令来编译Java程序了。如果我们直接在命令行窗口里输入javac,不跟任何选项和参数,系统将会输出大量提示信息来提示javac命令的具体用法,读者可以参考该提示信息来使用javac命令。对于初学者来说,建议先掌握javac命令的如下用法。
javac -d destdir srcFile
在上面命令中,-d destdir是javac命令的选项,功能是指定编译生成的字节码文件的存放路径,destdir值需要是本地磁盘上的一个合法有效路径。srcFile表示Java源文件所在的位置,此位置既可是绝对路径,也可以是相对路径。通常总是将生成字节码文件放在当前路径下,当前路径可以用点“.”来表示。如果想在命令行进入前面编写的文件first.java所在的路径,在该路径下应该输入如下命令。
javac -d . first.java
假设文件first.java所在的路径为“E:\daima\2”,则整个编译过程在CMD界面中的具体效果如图2-15所示。
图2-15 CMD中的编译过程
在图2-15中,“cd”命令的功能是进入某一个指定的子目录,例如“cd daima”就是表示进入E盘中“daima”文件夹。运行上述命令后会在该路径下生成一个first.class文件,如图2-16所示。
图2-16 生成first.class文件
编译之后我们需要使用java命令来运行Java程序,启动命令行窗口进入HelloWorld.class所在的位置,在命令行窗口里直接输入不带任何参数或选项的java命令后,可以看到系统输出大量提示,告诉开发者如何使用java命令。使用java命令的语法格式如下所示。
java java程序中的类名
一定要注意,java命令后的参数是Java程序的类名,既不是字节码文件的文件名,也不是Java源文件名。例如我们可以通过命令行窗口进入first.class所在的路径,输入命令如下所示。
java first
运行上面命令,将看到输出如下结果。
第一段Java程序!
初学者经常容易忘记Java是一门区分大小写的语言,例如在下面的运行命令中错误地将first写成了First,就会造成运行异常。
java First
知识点讲解:光盘:视频\PPT讲解(知识点)\第2章\使用IDE工具.mp4
在本章2.2节中的体验Java程序的过程中,发现这样编写、编译、运行程序的过程非常烦琐。为了提高开发效率,我们可以使用第三方工具来帮助我们。在本节的内容中,将讲解几种主流IDE开发工具的基本知识,以帮助读者提高开发Java程序效率。
Eclipse是一个开放源代码的软件开发项目,是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,Eclipse只是一个框架和一组服务,能够通过插件和组件来构建开发环境。
在Eclipse中附带了一个标准的插件集,在里面包括了Java开发工具(Java Development Tools,JDT)。Eclipse专注于为高度集成的工具开发提供一个全功能的、具有商业品质的工业平台。它主要由Eclipse项目、Eclipse工具项目和Eclipse技术项目3个项目组成,具体来说由如下4个部分组成。
虽然大多数用户很乐于将Eclipse当作Java IDE来使用,但Eclipse的目标不仅限于此。Eclipse还包括插件开发环境(Plug-in Development Environment,PDE),这个组件主要针对希望扩展Eclipse的软件开发人员,因为它允许他们构建与Eclipse环境无缝集成的工具。由于Eclipse中的每样东西都是插件,对于给Eclipse提供插件,以及给用户提供一致和统一的集成开发环境而言,所有工具开发人员都具有同等的发挥场所。
Eclipse是著名的跨平台的集成开发环境(IDE),Eclipse的本身只是一个框架平台,但是众多插件的支持使得Eclipse拥有其他功能相对固定的IDE软件很难具有的灵活性。许多软件开发商以Eclipse为框架开发自己的IDE。图2-17所示为Eclipse启动界面。
图2-17 Eclipse启动界面
Eclipse是一个免费的开发工具,用户可以去官方网站进行下载即可获得,具体获取过程如下所示。
(1)打开IE浏览器,在浏览器中输入网址“http://www.Eclipse.org/”,然后单击“Download Eclipse”超级链接,如图2-18所示。
图2-18 Eclipse的首页
(2)进入“Eclipse”下载页面,在“Eclipse IDE for Java EE Developers (189 MB)”栏中,根据操作系统选择“Eclipse”版本,在此单击“Windows”超级链接,如图2-19所示。
图2-19 下载页面
(3)单击“[China] Actuate Shanghai (http)”超级链接开始下载Eclipse,笔者使用了“迅雷”进行下载,如图2-20所示。
图2-20 下载Eclipse
解压缩下载的Eclipse文件,然后双击文件“eclipse.exe”启动Eclipse。新建Eclipse项目的操作过程如下所示。
(1)在任意一个盘里新建一个文件夹,如这里在F盘新建“open”文件夹,然后在“Workspace”文本框中输入地址,单击“OK”按钮,如图2-21所示。
图2-21 指定项目文件夹
(2)在顶部菜单栏中依次单击“File”|“New”|“Project”命令新建一个项目,如图2-22所示。
图2-22 选择命令
(3)在打开的“New Project”对话框中单击“Java”选项,然后在下面打开“Java Project”选项,选择后单击“Next”按钮,如图2-23所示。
图2-23 “New Project”对话框
(4)在打开的对话框中,在“Project name”文本框中输入项目名称,例如输入“one”,输入完成后单击“Finish”按钮,如图2-24所示。
图2-24 新建项目
(5)在Eclipse的左侧双击项目“One”,选择“str”选项,单击鼠标右键,在弹出的快捷菜单中,选择“New/Class”命令,如图2-25所示。
图2-25 选择命令
(6)打开“Java Class”对话框,在“Name”文本框中输入类名,如“Hi”,选择复选框,然后单击“Finish”按钮,如图2-26所示。
图2-26 “Java Class”对话框
(7)然后打开“Hi”文件,输入代码,输入完成后的效果如图2-27所示。
图2-27 输入代码
(8)编译代码后单击按钮后打开“Save and Launch”对话框,然后单击“OK”按钮,如图2-28所示。
图2-28 编译Java
(9)单击“OK”按钮后即可看到运行后的结果,如图2-29所示。
图2-29 运行后的结果
注意:对于初学者来说,建议使用Eclipse新建项目后,直接使用Eclipse编辑器全部手动编写代码,这样可以帮助我们快速掌握Java语言的语法知识,通过实例巩固所学的知识。
NetBeans是由原来Sun建立的开放源码的软件开发工具,是一个开放框架,可扩展的开发平台,可以用于Java、C/C++等的开发,本身是一个开发平台,可以通过扩展插件来扩展功能。
NetBeans是Sun公司在2000年创立的,它是开放源运动以及开发人员和客户社区的家园,旨在构建世界级的Java IDE。NetBeans当前可以在Solaris、Windows、Linux和Macintosh OS X平台上进行开发,并在SPL(Sun公用许可)范围内使用。http://www.netbeans.org已经获得业界的广泛认可,并支持NetBeans扩展IDE模块目录中的100多个模块。
NetBeans是一个全功能的开放源码Java IDE,可以帮助开发人员编写、编译、调试和部署Java应用,并将版本控制和XML编辑融入其众多功能之中。NetBeans 可支持Java 2平台标准版(J2SE)应用的创建、采用JSP和Servlet的2层Web应用的创建,以及用于2层Web应用的API及软件的核心组的创建。此外,NetBeans 最新光盘还预装了两个Web服务器,即Tomcat和GlassFish,从而免除了烦琐的配置和安装过程。所有这些都为Java开发人员创造了一个可扩展的开放源多平台的Java IDE。
你可以通过NetBeans获得更多的开发工具,包括建立桌面应用、企业级应用、Web开发和Java移动应用程序开发、C/C++,甚至Ruby。NetBeans支持多种操作系统平台,包括Windows、Linux、Mac OS和Solaris等操作系统。
NetBeans是一款免费的软件,读者可以去官方站点下载获取,具体获取流程如下所示。
(1)在IE地址栏中输入“http://www.netbeans.org/”,然后在页面下载Netbeans,单击“Download NetBeans IDE”按钮,如图2-30所示。
图2-30 单击超级链接
(2)在打开的页面中,用户可以根据自己的需要进行下载,这里单击“All”下的“下载”按钮,如图2-31所示。
图2-31 下载“NetBeans IDE”
(3)单击“请点击这里下载”按钮,然后将自动下载工具,这里的“下载工具”是迅雷,将自动启动迅雷,然后单击“立即下载”按钮,如图2-32所示。
图2-32 启动迅雷进行下载
下载NetBeans完成后可以安装NetBeans,安装过程十分简单,具体安装流程如下所示。
(1)双击“NetBeans”按钮打开“NetBeans”安装向导,然后在欢迎界面中单击“定制”按钮,如图2-33所示。
图2-33 欢迎界面
(2)打开“定制安装”对话框,在列表框中选择需要的组件,然后单击“确定”按钮,如图2-34所示。
图2-34 选择组件
(3)返回到欢迎界面,单击“下一步”按钮,然后在“许可证协议”窗口中勾选,然后单击“下一步”按钮,如图2-35所示。
图2-35 “许可证协议”对话框
(4)打开“NetBeans IDE 6.7安装”对话框,在“将NetBeans IDE安装到以下位置”文本框中输入下载位置,然后在“用于NetBeans IDE的JDK”文本框中设置JDK的位置,单击“下一步”按钮,如图2-36所示。
图2-36 “NetBeans IDE安装程序”对话框
(5)在“Apache Tomcat 6.0.18安装”对话框中指定Tomcat的安装位置,然后单击“下一步”按钮,如图2-37所示。
图2-37 指定Tomcat的位置
(6)在打开的“摘要”对话框中可以看到具体的安装位置,单击“安装”按钮开始进行安装,如图2-38所示。
图2-38 安装文件
(7)整个安装的过程需要一定的时间,在“安装”对话框中会用一个进度条来提示进度,如图2-39所示。
图2-39 安装Netbeans
(8)在“安装完成”窗口中依次选择复选框和
复选框,然后单击“完成”按钮,如图2-40所示。
图2-40 完成安装
使用NetBeans新建Java项目的操作方法十分简单,其具体操作流程如下所示。
(1)双击NetBeans桌面图标,启动NetBeans软件,如图2-41所示。
图2-41 启动NetBeans IDE软件
(2)在菜单栏中依次单击“文件”|“新建项目”命令即可新建一个Java项目,如图2-42所示。
图2-42 新建项目
(3)打开“新建项目”对话框,在左边“类别”选择需要的类,例如选择Java,然后在“项目”类别选择项目的类别,例如Java应用程序,如图2-43所示。
图2-43 选择项目的类别
(4)选择后单击“下一步”按钮,在对话框中设置项目的名称、项目位置以及创建主类的名称,如图2-44所示。
图2-44 创建项目
(5)进入创建的项目,打开新建的类开始编写程序,输入程序完成后,单击按钮开始进行调试运行,会得到如图2-45所示的结果。
图2-45 NetBeans 调试的结果
JBuilder是Borland公司开发的针对Java的开发工具,使用JBuilder将可以快速、有效地开发各类Java应用程序,它使用的JDK与Sun公司标准的JDK不同,它经过了较多的修改,以便开发人员能够像开发Delphi应用那样开发Java应用。
JBuilder的核心有一部分采用了VCL技术,利用它编写的代码即使是初学者也可以读懂。JBuilder的另外一个好处是通过互联网,将分布在世界不同地方的开发人员联合起来开发项目。
知识点讲解:光盘:视频\PPT讲解(知识点)\第2章\Java的运行机制.mp4
Java语言是一种特殊的高级语言,它不但有解释性语言的特征,也有编译性语言的特征,我们需要先编译Java程序,然后解释运行Java程序。在本章2.2节的内容中,通过一段Java程序了解了编译并运行Java程序的基本方法。我们只是从表面上了解了Java程序的编译和运行流程,为了加深对Java的理解,在本节将从根本上讲解Java程序的运行机制。
高级语言有两种执行程序的方式,分别是编译型和解释型。
编译型的语言指使用专门的编译器、针对特定平台(操作系统)将某种高级语言源代码一次性“翻译”成可被该平台硬件执行的机器码(包括机器指令和操作数),并包装成该平台所能识别的可执行性程序的格式,这个转换过程称为编译(Compile)。编译后会生成一个可以脱离开发环境的可执行性程序,可以在很多特定的平台上独立运行。
有些程序编译结束后,还可能需要对其他编译好的目标代码进行链接,即组装两个以上的目标代码模块生成最终的可执行性程序,通过这种方式实现低层次的代码复用。
因为编译型语言是一次性地编译成机器码,所以可以脱离开发环境独立运行,而且通常运行效率较高;但因为编译型语言的程序被编译成特定平台上的机器码,因此编译生成的可执行性程序通常无法移植到其他平台上运行;如果需要移植,则必须将源代码复制到特定平台上,针对特定平台进行修改,至少也需要采用特定平台上的编译器重新编译。现有的C和C++等高级语言都属于编译型语言。
解释型语言是指使用专门的解释器对源程序逐行解释成特定平台的机器码并立即执行的语言,解释型语言通常不会进行整体性的编译和链接处理,解释型语言相当于把编译型语言中的编译和解释过程混合到了一起同时完成。可以认为:每次执行解释型语言的程序都需要进行一次编译,因此解释型语言的程序运行效率通常较低,而且不能脱离解释器独立运行。但解释型语言有一个优势:跨平台比较容易,只需提供特定平台的解释器即可,每个特定平台上的解释器负责将源程序解释成特定平台的机器指令即可。解释型语言可以方便地实现源程序级的移植,但这是以牺牲程序执行效率为代价的。现有的Ruby、Python等语言都属于解释型语言。
Java语言比较特殊,由Java语言编写的程序必须经过编译步骤,但这个编译步骤并不会生成特定平台的机器码,而是生成一种与平台无关的字节码(也就是*.class文件)。当然这种字节码不是可执行性的,必须使用Java解释器来解释执行。正是因为此,可以认为Java既是一种编译型语言,也是一种解释型语言。
在Java语言中,负责解释执行字节码文件的是Java虚拟机,即JVM (Java Virtual Machine)。JVM是可运行Java字节码文件的虚拟计算机。所有平台上的JVM向编译器提供相同的编程接口,而编译器只需要面向虚拟机,生成虚拟机能理解的代码,然后由虚拟机来解释执行。在一些虚拟机的实现中,还会将虚拟机代码转换成特定系统的机器码执行,从而提高执行效率。
当使用Java编译器编译Java程序时,会生成与平台无关的字节码,这些字节码不面向任何具体平台,它只面向JVM。不同平台上的JVM都是不同的,但它们都提供了相同的接口。JVM是Java程序跨平台的关键部分,只要为不同平台实现了相应的虚拟机,编译后的Java字节码就可以在该平台上运行。由此可见,几乎不可能在不同的平台上运行相同的字节码程序,而只能通过中间的转换器JVM才可以实现。
Java中的命名规则有很多,例如变量命名规则和类命名规则等,而在此讲解的是Java源文件的命名规则。在编写Java程序时,源文件名字不能随便起,需要遵循下面的两个规则。
根据上述规则,我们可以得出命名程序文件的如下3个建议。
有很多初学者经常犯一个错误,即在保存一个Java文件时经常保存成形如“*.java.txt”格式的文件名,因为这种格式文件名从表面看起来太像是“*.java”了,所以经常会引发错误。要想解决这个粗心的错误,我们可以修改Windows的默认设置。因为Windows系统的默认设置是“隐藏已知文件类型的扩展名”,所以我们只需将此设置选项取消勾选即可,如图2-46所示。
图2-46 取消勾选“隐藏已知文件类型的扩展名”选项
Java的JDK经过了几年的发展,已经发展到了现在的JDK-7系列,即JDK1.7。新的JDK更加成熟,速度也更快。但是往往程序员总是难以忘记以前版本的一些特点和用法,经常会不自觉地在新版本中按照旧版本的方式进行操作。例如最常见的就是环境变量问题,本章2.1.2节中已经介绍了设置环境变量的问题。其实对于开发纯Java项目来说,如果使用的是JDK1.5以上的版本,则完全不用画蛇添足般地设置环境变量。
设置CLASSPATH环境变量会比较麻烦,在设置CLASSPATH环境变量后,Java解释器会在当前路径搜索Java类,例如在first.class文件所在路径运行java first将没有任何问题。但如果设置了CLASSPATH环境变量,Java解释器会只在CLASSPATH环境变量所指定的系列路径中搜索Java类,这样就容易出现问题了。
在当今很多教科书和资料中,都提到过在CLASSPATH中添加dt.jar和tools.jar这两个文件的教程,所以很多初学者会将CLASSPATH变量的值设置为如下形式。
D:\Java\jdkl.6.0_03\lib\dt.jar;D:\Java\jdkl.7.0_01\lib\tools.jar
这样做会导致Java解释器不在当前路径下搜索Java类,此时如果在文件first.class所在路径运行java first会出现如图2-47所示的错误提示。
图2-47 错误提示
造成上述错误的原因是找不到类定义,这是由于CLASSPATH环境变量设置不正确造成的。所以在此建议广大读者,在设置CLASSPATH环境变量时一定不要忘记在CLASSPATH环境变量中增加一点“.”,强制Java解释器在当前路径搜索Java类。
Java语言是严格区分大小写的语言,但是很多初学者对大小写问题往往都不够重视。例如有的读者编写的Java程序里的类是“first”,但当他运行Java程序时运行的是“java First”的形式。所以在此因此提醒读者必须注意,在Java程序中的First和first是不同的,必须严格注意Java程序中大小写的问题。在此建议广大读者,在按照书中实例程序编写Java代码时,必须严格注意Java程序中每个单词的大小写,不要随意编写,例如class和Class是不同的两个词,class是正确的,但如果写成Class则程序无法编译通过。这是因为Java程序里的关键字全部是小写的,无须大写任何字母。
如果需要用Java解释器直接运行一个Java类,则这个Java类必须包含main()方法。在Java中必须使用public和static来修饰main(),并且必须使用void来声明该方法的返回值,而且该方法的形参只能是一个字符串数组,而不能是其他形式的参数。对于这个main()方法来说,修饰它的修饰符public和static的位置可以互换,但其他部分则是固定的。
在定义main()方法时也需要注意大小写的问题,如果不小心把方法名的首字母写成了大写,编译时不会出现任何问题,但运行该程序时将引发错误。
空格问题是初学者很容易犯的一个错误,在Windows系统中的很多路径都包含有空格,例如C盘中的“Program Files”,而这个文件夹恰好是JDK的默认安装路径。如果在CLASSPATH环境变量中包含的路径中含有空格,则可能会引发错误。所以推荐大家在安装JDK和Java相关程序/工具时,不要安装在包含空格的路径里,否则可能引发错误。
笔者对初学者的建议是:在初期尽量不要使用IDE工具,但是现在一个追求速成的年代,大多数人都希望用最快的速度掌握Java技术。其实市面中的IDE工具居多,除了Eclipse、Jbuilde和NetBeans之外,还有IBM提供的WSAD、JetBrains提供的IntelliJ IDEA、IBM提供的VisualAge、Oracle提供的JDeveloper、Symantec提供的Visual Cafe以及BEA提供的WorkShop,每个IDE都各有特色,各有优势。如果从工具学起,势必造成对工具的依赖,当换用其他IDE工具时会变得极为困难。而如果从Java语言本身学起,把Java语法和基本应用熟记于心,到那时再使用IDE工具才会得心用手。
在我们日常使用的Windows平台上可以选择记事本来编码,如果嫌Windows下记事本的颜色太单调,可以选择使用EditPlus或UltraEdit工具。
如果实在要用IDE工具,例如Eclipse,则建议纯粹将它作为一款编辑器来用,将所有代码靠自己一个个字符敲打并输入来完成,而不是靠里面的帮助文档和操作菜单来完成编码工作。
对于很多初学者来说,对JDK和JRE两者比较迷糊,不知道到底有什么异同。
Sun把Java分为Java SE、Java EE和Java ME三部分,而且为Java SE和Java EE分别提供了JDK和Java EE SDK (Software Development Kit)两个开发包。如果读者只学习Java SE的编程知识,可以下载标准的JDK,如果学完Java SE之后还需要继续Java EE相关内容,也可以选择下载Java EE SDK。因为有一个Java EE SDK版本里已经包含了最新版的JDK,所以在安装的Java EE SDK中已经包含了JDK。
一般来说,如果我们只是要运行Java程序,可以只安装JRE,而无须安装JDK。但是如果要开发Java程序,则应该安装JDK。安装JDK之后就包含JRE了,也可以运行Java程序。但如果只是需要运行Java程序,而不是开发Java程序,则只需在计算机上安装JRE即可。