• 2.09 MB
  • 331页

公路工程标准化指南 公路建设标准化在西藏的应用初探

  • 331页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
'北京尚学堂科技JAVA基础课程JAVA基础课程讲义内部资料(禁止外传)331 北京尚学堂科技JAVA基础课程内部资料北京尚学堂科技目录第一章JAVA入门10计算机语言发展史10机器语言10汇编语言10高级语言10其他高级语言11JAVA发展简史12JAVA为什么能够流行?13JAVA各版本的含义13JAVA技术体系架构14JAVA的特性和优势14JAVA应用程序的运行机制15JVM(JAVAVIRTUALMACHINE)16Java运行时环境JRE(JavaRuntimeEnvironment)17JAVA语言应用范围18第一个JAVA程序18JAVA开发环境搭建18331 北京尚学堂科技JAVA基础课程一个典型的JAVA程序的编写和运行过程19第一个程序常见错误20第一个JAVA程序的总结和提升20常用Java开发工具20常用dos命令21本章笔试作业21本章上机操作21第二章(1)编程的基本概念22注释22标识符22关键字/保留字23变量(variable)24常量(Constant)25命名规则(规范)25基本数据类型(primitivedatatype)26整型变量26浮点型27字符型(2个字节):28boolean类型29运算符(operator)29二元运算符29一元运算符30布尔逻辑表达符30位运算符30扩展运算符31字符串连接符31三目条件运算符31运算符优先级的问题31331 北京尚学堂科技JAVA基础课程自动类型转换32基本类型转化时常见错误和问题33方法33简单的键盘输入和输出33本章思考作业34上机操作34第二章(2)控制语句35顺序结构35选择结构35if单选择结构35if-else双选择结构35If-elseif-else多选择结构36switch多选择结构37循环结构39While和dowhile的区别41For循环42break语句和continue语句47语句块48递归结构49本章作业50本章上机操作51第三章JAVA面向对象程序开发52编程语言发展史52类和对象是如何产生发展的?如何进化的?52面向对象思想初步(OOP初步ObjectOrientedProgramming)53面向对象编程的语言的三大特征简介56对象和类的概念56类和对象初步57331 北京尚学堂科技JAVA基础课程测试类的定义方式57简单的学生类编写示例58内存分析59属性(field,或者叫成员变量)59引用类型60类的方法60对象的创建和使用60构造器(或者叫做构造方法,constructor)60垃圾回收机制(GarbageCollection)63方法的重载(overload),构造方法的重载63this关键字65static关键字66静态初始化块(经常用来初始化类,加载类信息时执行!)67package68JDK中的主要包68import68eclipse的使用69继承(extend,inheritance)70为什么需要继承?继承的作用?70继承介绍70如何实现继承?70继承使用要点71Object类72toString方法72equals方法73super关键字74方法的重写(override)74隐藏/封装(encapsulation)75331 北京尚学堂科技JAVA基础课程为什么需要封装?封装的作用和含义?75使用访问控制符,实现封装76封装的使用细节76多态(polymorphism)76为什么需要多态?76如何实现多态?77方法绑定(methodbinding)77静态绑定77动态绑定77多态的使用要点78对象的转型(casting)79final81抽象类82抽象类的使用要点83接口83为什么需要接口?84如何定义接口?84接口的本质探讨84接口使用要点85接口的多继承86面向接口编程87OOP更多应用87组合87内部类(innerclasses)88字符串(java.lang.String类)的使用90字符串相等的判断92思考作业93上机作业94331 北京尚学堂科技JAVA基础课程第四章异常机制95导引问题95异常(Exception)的概念96异常分类96Error97Error和Exception的区别97Exception97异常的处理办法之一,捕获异常99try块99catch99finally100try,catch,finally,return执行顺序100异常的处理办法之二,声明异常:throws子句101方法重写中声明异常原则102异常的处理办法之三,手动抛出异常,throw子句103自定义异常103使用异常机制建议104总结105思考作业105上机作业105第五章数组106数组概述和特点106创建数组和初始化106数组常见操作108数组的拷贝108数组排序109多维数组110附录(面试前复习一下!!)111331 北京尚学堂科技JAVA基础课程冒泡排序111二分法查找112命令行参数的问题113增强for循环114思考作业114上机作业115第六章常用类的使用117基本数据类型的包装类117包装类基本知识117包装类的用途118自动装箱和拆箱?autoboxing,unboxing119字符串相关类(String、StringBuffer、StringBuilder)120String类的常用方法(已讲过,不再讲!)120StringBuffer和StringBuilder121String和StringBuffer和StringBuilder使用要点123时间处理相关类124Date时间类(java.util.Date)124DateFormat类和SimpleDateFormat类125Calendar日历类126可视化日历的编写128Math类131File类132File类的基本用法132树状结构展现文件结构133枚举133上机作业135第七章容器(Collection)136容器的作用和概览136331 北京尚学堂科技JAVA基础课程容器中的接口层次结构136Collection接口137LIST接口137SET接口138Map接口138Iterator接口139遍历集合140Collections工具类141Comparable接口141equals和hashcode方法143Ø泛型144思考作业145上机作业145第八章IO技术146为什么需要学习IO技术146基本概念146数据源146流的概念146第一个简单的IO流程序及深入(将文件中的数据读入)146Java中流的概念细分148Java中IO流类的体系149四个IO基本抽象类150InputStream150OutputStream150常用InputStream和OutputStream子类用法150FileInputStream和FileOutputStream150ByteArrayInutStream和ByteArrayOutputStream154BufferedInputStream和BufferedOutputStream156331 北京尚学堂科技JAVA基础课程DataInputStream和DataOutputStream157ObjectInputStream和ObjectOutputStream158PrintStream158Reader158Writer159FileReader和FileWriter159BufferReader和BufferWriter159InputStreamReader和OutputStreamWriter161JAVA对象的序列化和反序列化161为什么需要序列化和反序列化161对象的序列化主要有两种用途161序列化涉及的类和接口162序列化/反序列化的步骤和实例162综合的序列化和反序列化练习163JAVA.IO包相关流对象用法总结(尚学堂1002班王鑫)165IO中其他常用类165File类165RandomAccessFile166思考作业166上机作业166提高课外作业166第九章多线程技术167基本概念167程序167进程167线程167线程和进程的区别167进程与程序的区别168331 北京尚学堂科技JAVA基础课程JAVA中如何实现多线程(重点!!)168通过继承Thread类实现多线程168通过Runnable接口实现多线程169线程状态和sleep/yield/join/stop/destroy方法170新生状态170就绪状态170运行状态170死亡状态170终止线程的典型方法(重要!!!)171阻塞状态(sleep/yield/join方法)171线程基本信息和优先级别173线程同步和死锁问题175死锁及解决方案179生产者/消费者模式181线程回顾总结184任务调度(补充内容,了解即可!)184思考作业185上机作业185第十章网络编程186基本概念186什么是计算机网络186计算机网络的主要功能186什么是网络通信协议186网络通信接口186为什么要分层186通信协议的分层规定186数据封装188数据拆封188331 北京尚学堂科技JAVA基础课程IP188端口188URL189TCP协议和UDP协议189区别189TCP协议189UDP协议190JAVA网络编程190InetAddress190InetSocketAddress191URL类191基于TCP协议的SOCKET编程和通信193UDP通讯的实现201思考作业203上机作业(分组完成,3人一组,周末完成)204第十一章JAVA多媒体编程205字体205字体示例和效果205颜色206颜色编程示例206图形绘制206绘制各种图形示例207图像处理208加载图片示例208图片任意缩放并输出新图片209使用JMF处理音频和视频211JMF的下载211JMF的安装和配置211331 北京尚学堂科技JAVA基础课程使用JMF播放音频文件212上机作业213第十二章GUI编程之AWT214为什么需要GUI?GUI是什么?214AWT是什么?214AWT的优势214AWT的缺点214为什么还需要学习AWT?215AWT各组件的整体关系215组件215容器216布局管理器218为什么需要布局管理器?218FlowLayout布局管理器218BorderLayout布局管理器219CardLayout布局管理器220GridLayout布局管理器220GridBagLayout布局管理器221综合应用组件和容器和布局管理器221AWT事件处理模型223问题223事件处理模型是什么?223最简单的事件处理程序224AWT中事件处理代码编写225编写过程225处理过程225简化理解上面过程225事件和事件源对象225331 北京尚学堂科技JAVA基础课程事件适配器232为什么需要事件适配器232事件监听器常见的定义形式233AWT其他组件233菜单的实现233特点233代码示例和效果233331 北京尚学堂科技JAVA基础课程第一章JAVA入门计算机语言发展史机器语言每一个计算机只能理解他自己的机器语言。机器语言对于计算机来说就是自然语言了,由计算机硬件的设计者定义。机器语言通常有数字串组成(最终被简化成01),对于人类来说,机器语言过于繁琐。这个任务的实现:基本费用(basepay)+超时费用(overpay)=总费用(totalpay)典型的机器语言:汇编语言为了编程的方便,以及解决更加复杂的问题。程序员开始使用英文的缩写的助记符来表示基本的计算机操作。这些助记符构成了汇编语言的基础。典型的汇编语言:高级语言对于简单的任务,汇编语言可以胜任。但是随着计算机的发展,渗透到了工作生活的更多的方面,一些复杂的任务出现了,汇编语言就显得有限力不从心(应该说是程序员使用汇编语言解决复杂问题出现了瓶颈)。于是,出现了高级语言。像c,c++,java都是高级语言。高级语言允许程序员使用接近日常英语的指令的编写程序。Grosspay=basepay+overpay;从上面这个简单的加法计算,可以看出越到高级语言,越接近人的思维,人使用起来越方便。总结:331 北京尚学堂科技JAVA基础课程所有的编程语言的最终目的都是提供一种“抽象”方法。抽象的层次越高,越接近人的思维。编程的最终目的还是为了解决现实问题!现在编程语言c的诞生:C是人们追求结构化、高效率、高级语言的直接结果,他可以替代汇编语言来开发系统程序。Fortran虽然适合编写科学计算方面的程序,但是不适于编写系统程序。Basic虽然易学,但是功能不够强大,应用到大程序的有效性令人怀疑。汇编语言虽然能编写高效率的程序,但是学习和使用都不是易事,并且很难调试。另一个复杂的问题,早期的计算机语言(basic,fortran,cobolPascal是结构化的,不过设计效率低下。等)没有考虑结构化设计原则,而是使用goto语句来作为程序控制的主要方法。这样做的后果是:一大堆混乱的调转语句使得程序几乎不可能被读懂。C++的出现:为什么语言需要向高级方面发展?为什么语言会像人的思维的发展?这是由于处理问题的复杂性(complexity)。计算机刚出来的时候,编程是通过面板触发器用人工打孔的方法输入二进制指令来实现,对于只有几百行的程序,这种办法是可行的。也就是说他只能解决简单的问题。后来出现的汇编语言,用符号来代替机器指令,这样程序员就可以处理更加复杂的问题。第一个被广泛使用的高级语言是fortran,但是他出现的时间太早,大约在1954年,所以没有结构化设计的概念,无法开发出条例清晰易于理解的程序;60年代出现的c,程序员第一次可以通过结构化的理念编写出易于理解的复杂程序;尽管c是一个伟大的语言,但是程序的代码量达到25000-30000行以上时,程序员就不能很好的从总体上把握和控制这个程序。因此,在80年代初期,很多软件项目都面临无法解决的问题而不能顺利进行。1979年,stroustrop发明的c++。C++最初的名字叫做“带类的c”,后来才改名叫c++。C++的发展历史C语言是由B语言发展而来,他们都是贝尔实验室创造的。C于1972年出现。作为C的扩展,C++是贝尔实验室于80年代出现的。C++是一种混合语言,既可以实现面向对象编程,也可以开发C风格的程序。331 北京尚学堂科技JAVA基础课程其他高级语言Fortran:是IBM在1954年提出的。主要用在要求复杂数学计算的科学和工程领域。现在仍然被广泛使用,尤其是工程领域。COBOL:于1959年提出。主要用于大量精确处理数据的商业领域中,比如金融、银行。今天,仍然有超过一半的商业软件使用COBOL编写。有将近100万人使用COBOL编程。PASCAL:几乎和C同时提出。是nicklauswirth教授为了大学教授编写的。由于没有大厂商和政府的支持,只是限于大学教育这一块。ADA:ada以pascal为基本参照,是美国国防部(DOD)为了编写他庞大的命令和控制系统软件而设计的。他的一个重要的特性就是多任务,使用它编写的程序可以同时处理多项事务。JAVA也支持多线程。其实,高级语言也分为:面向过程和面向对象。面向对象和面向过程的区别:1.开车a)启动点火b)离合器c)挂档d)油门2.造车(比较复杂!使用简单的线性的思维无法解决!)a)发动机i.塑模ii.造出b)轮胎i.去马来西亚买橡胶ii.造轮胎331 北京尚学堂科技JAVA基础课程a)椅子b)方向盘c)车皮面向对象是从整体上/宏观上把握所要处理的事情.面向过程是从微观上/细节上处理具体的事物.JAVA发展简史在1991年时候,JamesGosling在sun公司的工程师小组想要设计这样一种小型计算机语言。该语言主要用于像电视盒这样的消费类电子产品,这些电子产品有一个共同的特点:计算处理能力和内存都非常有限。所以要求:语言必须非常小且能够生成非常紧凑的代码,这样才能在这样的环境中执行。另外,由于不同的厂商选择不同的CPU,因此,要求该语言不能和特定的体系结构绑在一起,要求语言本身是中立的,也就是跨平台的。所以,将这个语言命名为“Green”,类似于绿色软件的意思。后来,改名将OAK。橡树的意思。改名后发现已经有一种语言叫这个名字了,在改名叫JAVA.1991年,Sun公司的Green项目,Oak1995年,推出Java测试版1996年,JDK1.01997年,JDK1.11998年,JDK1.2,大大改进了早期版本的缺陷,是一个革命性的版本,更名为Java2。2004年,J2SE5.0(1.5.0)Tiger老虎2006年,J2SE6.0(1.6.0)Mustang野马JAVA为什么能够流行?C331 北京尚学堂科技JAVA基础课程++已经是非常完美的面向对象的编程语言,有所有面向对象的特性,而且有c的高效率、简洁,因此非常受欢迎。直到现在仍然被广泛使用。但是,随着Internet的爆发式的发展,促成了java的大发展。虽然internet的发展是java大发展的主要因素。但是,发明java的初衷却是用于消费类电子产品,比如:微波炉、遥控器等,用于这些产品的编程。因为这些产品CPU都是完全不同的,并且计算能力都非常有限以及内存非常有限。因此,我们需要JAVA语言需要符合两个特点:1.体系中立。JAVA需要能够生成运行于不同环境、不同CPU的代码。也就是代码的可移植性。2.代码紧凑。因为他的运行环境资源非常有限。但是,只能家电产品并没有像最初想象的那样大发展。JAVA最初只能是有用但是默默无闻。同时,internet却进入了他的爆发式发展阶段,一夜之间,大家都在谈论Inertnet,都在忙着将自己的计算机连接到网络上。这个时侯,遇到了一个大的问题。人们发现连接到internet的计算机各式各样,有IBMPC、苹果机、各种服务器等等,不仅硬件CPU不同,操作系统也不同,整个的网络环境是复杂的。这个时候,程序员们希望他们编写的程序能够运行在不同的机器,不同的环境中,这需要一种体系中立的语言,代码可移植。网络之间传送信息的效率较低,因此,也需要代码紧凑提高效率。JAVA的研发小组忽然发现他们用于小范围的语言也可以适应Internet这个大环境。因此,他们将自己的研发重点从消费类电子产品转向了internet编程。受JAVA影响最大的是c#,他是微软推出的和java抗衡的语言,用于支持.net框架。C#总体上和java非常相似。JAVA各版本的含义J2EE(Java2EnterpriseEdition):定位在服务器端的应用J2EE是J2SE的扩展,增加了用于服务器开发的类库。如:javax.servletEnterpriseJavaBeans是一种用来代表企业逻辑的软件组件;JDBC则是让程序人员能直接在Java内使用的SQL的语法来访问数据库内的数据;Servlet能够延伸服务器的功能,通过请求-响应的模式来处理客户端的请求;JSP是一种可以将Java程序代码内嵌在网页内的技术;另外还有包括XML、email及transaction等各种应用于服务器端的API。J2SE(Java2StandardEdition):定位在个人计算机上的应用这个版本是Java331 北京尚学堂科技JAVA基础课程平台的核心,它提供了非常丰富的API来开发一般个人计算机上的应用程序,包括用户接口AWT及Swing,网络功能与国际化、图像处理能力以及输入输出支持等。在互联网上大放异彩的Applet也属于这个版本。J2ME(JavaMicroEdition):定位在消费性电子产品的应用上J2ME是J2SE的内伸,包含J2SE的一部分核心类,也有自己的扩展类,增加了适合微小装置的类库:javax.microedition.io.*等。这个版本针对资源有限的电子消费产品的需求精简核心类库,并提供了模块化的架构让不同类型产品能够随时增加支持的能力。这个版本的应用层面相当广泛,会是未来Java平台发展的重点项目。JAVA技术体系架构JAVA的特性和优势简单性:就是c++语法的纯净版。没有头文件,指针运算,结构,联合,操作符重载,虚基类等等。由于语法基于c,因此学习起来完全不费力。331 北京尚学堂科技JAVA基础课程面向对象:面向对象是一种程序设计技术,他将重点放在数据(即对象)和对象之间的接口上。可移植性:这是JAVA的一个重要的优势。JAVA代码或者说字节码、二进制码可以跨平台的移植,而不用管具体的操作系统和硬件环境。JAVA本身就是面向网络的,只有在网络环境中才能显示出他的优势,比如:现在我有一个网络环境,要让我的笔记本和手机交互,笔记本环境是windows发出一个让手机定时录音的JAVA代码,手机只有简单Linux内核操作系统,照样可以完美的执行这个代码。“一次编写,随处运行”:“writeonce,runanywhere”JAVA在设计时就很注重移植和跨平台性。比如:JAVA的Int永远都是32位。不像c++可能是16,32,可能是根据编译器厂商规定的变化。这样的话程序的移植就会非常麻烦。高性能:JIT(JUSTINTIME)即时编译。将一些“热点”字节码编译成本地机器码,并将结果缓存起来,在需要的时候重新调用。这样的话,使JAVA程序的执行效率大大提高,某些代码甚至接待c++的效率。随着这种技术的一天天完善,也许有一天会超越编译代码的效率。分布式:JAVA是为internet的分布式环境设计的,因为他能够处理tcp/ip协议。事实上,通过url访问一个网络资源和访问本地文件是一样简单的。Java还支持远程方法调用(RMI,remotemethodInvocation),使程序能够通过网络调用方法。动态性:就是在需要时将某些代码添加到正在运行的程序中。反射机制。当需要把某些代码添加到正在运行的程序中时,动态性是一个非常重要的特性。Java的动态特性是其面向对象设计方法的扩展。它允许程序动态地装入运行过程中所需要的类,这是C++语言进行面向对象程序设计所无法实现的多线程多线程的使用可以带来更好的交互响应和实时行为。多线程的简单性是Java成为主流服务器端开发语言的主要原因之一。安全性Java适合于网络/分布式环境,为了达到这个目标,在安全性方面投入了很大的精力,使331 北京尚学堂科技JAVA基础课程Java可以构建防病毒,防篡改的系统。健壮性Java是一种健壮的语言,吸收了C/C++语言的优点,但去掉了其影响程序健壮性的部分(如:指针、内存的申请与释放等)。Java程序不可能造成计算机崩溃。Java系统仔细检测对内存的每次访问,确认它是合法的,而且不致引起任何问题。不过,即使Java程序也可能有错误。如果出现某种出乎意料之事,程序也不会崩溃,而是把该例外抛弃。再通过异常处理机制,程序就会发现这类例外,并加以处理。JAVA应用程序的运行机制计算机的高级编程语言类型:编译型,解释型Java语言是两种类型的结合;利用编辑器编写Java源程序à源文件名:主类名.java利用编译器(javac)将源程序编译成字节码à字节码文件名:源文件名.class利用虚拟机(解释器,java)解释执行:运行过程:载入、代码校验、解释执行331 北京尚学堂科技JAVA基础课程JVM(JAVAVIRTUALMACHINE)JVM是一种规范,可以使用软件比如各种软件实现的:IBM,SUN,BEA等。你也可以自己写一个JVM来实现,也可以使用硬件比如intel公司正在研发的java芯片来实现,就是一个虚拟的用于执行bytecodes字节码的计算机。他也定义了指令集、寄存器集、结构栈、垃圾收集堆、内存区域。JVM负责将java字节码解释运行,边解释边运行,这样,速度就会受到一定的影响。JAVA提供了另一种解释运行的方法JIT(justintime),可以一次解释完,再运行特定平台上的机器码,高级的JIT可以只能分析热点代码,并将这些代码转成本地机器码,并将结果缓存起来,下次直接从内存中调用,这样就大大提高了执行JAVA代码的效率。这样就实现了跨平台、可移植的功能。1.JVM是指在一台计算机上由软件或硬件模拟的计算机;它类似一个小巧而高效的CPU。2.byte-code代码是与平台无关的是虚拟机的机器指令。3.java字节代码运行的两种方式:1)方式interpreter(解释)2)Just-in-time(即时编译):有代码生成器将字节代码转换成本机的机器代码,然后可以以较高速度执行。不同的操作系统有不同的虚拟机。Java虚拟机机制屏蔽了底层运行平台的差别,实现了“一次编译,随处运行”。331 北京尚学堂科技JAVA基础课程Java运行时环境JRE(JavaRuntimeEnvironment)JavaRuntimeEnvironment(JRE)包含:Java虚拟机、库函数、运行Java应用程序和Applet所必须文件Java2SDK(DevelopmentKit)包含:JRE的超集,包含编译器和调试器等用于程序开发的文件Java运行环境的三项主要功能:n加载代码:由classloader完成;n校验代码:由bytecodeverifier完成;n执行代码:由runtimeinterpreter完成。JDK和JRE:sdk(也就是jdk)是jre的超集,是在jre的基础上增加了编译器及其他一些开发工具。jre就是java运行时环境,包括了jvm和其它一些java核心api,任何一台电脑,只有安装了jre才可以运行java程序.总结:1.如果只是要运行JAVA程序,之需要JRE就可以。JRE通常非常小,也包含了JVM.331 北京尚学堂科技JAVA基础课程1.如果要开发JAVA程序,就需要安装JDK。JAVA语言应用范围1.桌面应用编程2.WEB客户端编程3.WEB服务器编程4.手机编程5.机器人编程第一个JAVA程序JAVA开发环境搭建1.下载:DownloadJ2SDK(Java2SoftwareDevelopmentKit)fromhttp://java.sun.com2.安装:runtheexecutable(跟普通软件安装一样,点击下一步就OK!)3.环境变量配置:环境变量(就是为相关命令提供一个路径信息,告诉他到哪里去找相关文件信息):设置:新增系统环境变量JAVA_HOME,设置为JDK的安装路径:331 北京尚学堂科技JAVA基础课程修改系统环境变量Path执行dos命令,系统会在path指定的路径中寻找该命令对应的可执行文件。比如:notepad,在最前面系统可能会有多个不同版本JDK。由于系统会从path目录中从前到后找相关命令,置于前面可以被先找到。追加%JAVA_HOME%bin,并以;和原路径分隔。再增加:“.;”。这是表示当前目录的意思。注意:(%JAVA_HOME%两个%号,引用已有的环境变量bin)classpath问题:如果使用jdk1.5以上就不需要配置这个环境变量!JRE会自动搜索当前路径下的类文件及相关jar文件1.测试安装:运行àcmdà输入命令:java–version:出现如下结果,则通过测试。2.在文本编辑器中编写程序:一个典型的JAVA程序的编写和运行过程1.编辑阶段:(程序员编辑代码并保存在磁盘上)publicclassWelcome{publicstaticvoidmain(String[]args){System.out.println("Hellojava!");}};保存为:Welcome.java331 北京尚学堂科技JAVA基础课程1.编译阶段。(编译器创建class字节码文件JAVA解释器可以理解的语言)1.进入java文件所在目录,执行命令:javacWelcome.java2.生成class文件执行:”JavaWelcome”后发生的事。就是3-5阶段。2.载入阶段程序在执行前必须首先放入内存中。这个过程是有类装载器将一个或多个class文件可以来自磁盘,也可以来自网络内容传输到内存中。”JavaWelcome”激活了java解释器(jvm),然后jvm调用类装载器载入welcome.class中的信息。3.代码校验JVM调用代码校验器检验加载的代码是否合法并且不会破坏java的安全性约束。由于JAVA代码在网络环境中传播,为了避免破坏用户的文件和系统,必须保证严格的安全约束。4.运行阶段计算机在CPU的控制下逐字节的执行这个程序。第一个程序常见错误³出现如下错误的原因:‘java’不是内部或外部命令,也不是可运行的程序或批处理文件。²设置path³编译javacTest.java,明明看到该文件,为何找不到?àHelloWorld.java.txt²显示扩展名!(详细列表/显示所有文件/标题栏地址栏全路径)³NoSuchMethodError:main²解决方案:该行代码敲错,确定是否是:publicstaticvoidmain(String[]args)331 北京尚学堂科技JAVA基础课程第一个JAVA程序的总结和提升nJava对大小写敏感,如果出现了大小写拼写错误,程序无法运行。n关键字public被称作访问修饰符(accessmodifier),用于控制程序的其它部分对这段代码的访问级别。n关键字class表明Java程序中的全部内容都包含在类中,Java是一种纯面向对象的语言。n一个源文件中至多只能有一个public的类声明,其它类的个数不限,如果源文件中包含一个public类,源文件名必须和它中定义的public的类名相同,且以“java”为扩展名。n一个源文件可以有多个classn正确编译后的源文件,会得到相应的字节码文件,编译器为每个类生成独立的字节码文件,且将字节码文件自动命名为类的名字且以“class”为扩展名。nmain方法是Java应用程序的入口方法,它有固定的书写格式:npublicstaticvoidmain(String[]args这个可以任意写。不过一般都是这么写){…}n在Java中,用花括号划分程序的各个部分,任何方法的代码都必须以“{”开始,以“}”结束,由于编译器忽略空格,所以花括号风格不受限制。nJava中每个语句必须以分号结束,回车不是语句的结束标志,所以一个语句可以跨多行。编程风格:1.注意缩进!2.成对编程!常用Java开发工具文本编辑器nUltraEditnEditPlusnnotepad++集成开发环境(IDE:Integrated Development Environment)331 北京尚学堂科技JAVA基础课程nJBuilder(http://www.borland.com)nEclipse(http://www.eclipse.org)****nNetBeans(http://java.sun.com)nWSAD(http://www.ibm.com)常用dos命令1.cd进入一个目录2.cd..3.dir4.上下键:查找敲过的命令5.Tab键:自动补齐命令本章笔试作业1.计算机语言发展史中的主线是什么?2.JAVA语言为什么可以超越C++,C成为使用人数第一的语言?3.JAVA的跨平台是怎么实现的?4.JDK,JRE,JVM的区别和联系?5.以下()不是JAVA的特点:a)平台无关性b)高可靠性和安全性c)指针运算d)分布式应用和多线程本章上机操作1.配置JAVA开发环境2.写出你的第一个java程序3.笔记软件:Onenote的使用331 北京尚学堂科技JAVA基础课程1.截屏软件:snagit的使用2.Word2007新功能:图表制作、表格、SMARTART等第二章(1)编程的基本概念注释n注释就是程序员为读者作的说明,是提高程序可读性的一种手段n在Java中,有2种表示注释的方法q//单行注释----注释内容从//到本行结尾q/*单行或多行注释*/n/**/注释不能嵌套nJava中的注释不会出现在字节码文件中。即JAVA编译器编译时会跳过注释语句。Doc注释???publicclassWelcome{//我是单行注释publicstaticvoidmain(String[]args/*我是行内注释*/){System.out.println("HelloWorld!");}331 北京尚学堂科技JAVA基础课程/*我是多行注释!我是多行注释!*/}标识符用作给变量、类和方法命名。注意:表示类名的标识符用大写字母开始。如:Man,GoodMan表示方法和变量的标识符用小写字母开始,后面的描述性词以大写开始。eat(),eatFood驼峰写法()Java标识符有如下命名规则:n标识符必须以字母、下划线_、美元符$开头。n标识符其它部分可以是字母、下划线“_”、美元符“$”和数字的任意组合。nJava标识符大小写敏感,且长度无限制。n不可以是Java的关键字。JAVA不采用通常语言使用的ASCII字符集,而是采用unicode这样的标准的国际字符集。因此,这里的字母的含义:英文、汉字等等。(不建议大家使用汉字来定义标识符!)各种字符集的关系?合法的标识符:331 北京尚学堂科技JAVA基础课程inta=3;int_123=3;int$12aa=3;int变量1=55;不合法的标识符:int1a=3;//不能用数字开头inta#=3;//不能包含#这样的特殊字符intint=3;//不能使用关键字关键字/保留字Java关键字是Java语言保留供内部使用的,如class用于定义类。关键字也可以称为保留字,它们的意思是一样的。abstractAssertbooleanbreakbytecasecatchchar(character)classconstcontinuedefaultdoDoubleelseextendsfinalfinallyfloatForgotoifimplementsimportinstanceofIntinterfacelongnativenewnullPackageprivateprotectedpublicreturnshortStaticstrictfpsuperswitchsynchronizedthisThrowthrowstransienttryvoidvolatileWhile不能使用关键字作为变量名或方法名。331 北京尚学堂科技JAVA基础课程变量(variable)我们通过变量来操纵存储空间中的数据,变量就是指代这个存储空间!空间位置是确定的,但是里面放置什么值不确定!Java是一种强类型语言,每个变量都必须声明其类型。nJava变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。n变量在使用前必须对其声明,只有在变量声明以后,才能为其分配相应长度的存储单元,声明格式为:qtypevarName[=value][{,varName[=value]}];n注意事项:q每个变量都有类型,类型可以是基本类型,也可以是引用类型。q变量名必须是合法的标识符。变量声明是一条完整的语句,因此每一个声明都必须以分号结束n变量声明举例:doublesalary;booleandone;longearthPopulation;intage;n可以在一行中声明多个变量:inti,j;//bothareintegersq不提倡这种风格,逐一声明每一个变量可以提高程序可读性。n可以将变量的声明和初始化放在同一行中,例如:intage=18;floate=2.718281828f;n变量可划分为:q局部变量(lacalvariable):方法或语句块内部定义的变量。生命周期是从声明位置开始到”}”为止。在使用前必须先声明和初始化(赋初值)。publicvoidincorrectLocalV(){inti;331 北京尚学堂科技JAVA基础课程i=10;intj=i+5;//编译出错,变量i还未被初始化}q实例变量(成员变量membervariable):方法外部、类的内部定义的变量。从属于对象,生命周期伴随对象始终。如果不自行初始化,他会自动初始化成该类型的默认初始值(数值型变量初始化成0或0.0,字符型变量的初始化值是16位的0u0000,布尔型默认是false)q静态变量(类变量staticvariable):使用static定义。从属于类,生命周期伴随类始终,从类加载到卸载。(注:讲完内存分析后我们再深入!先放一放这个概念!)如果不自行初始化,他会自动初始化成该类型的默认初始值(数值型变量初始化成0或0.0,字符型变量的初始化值是16位的0u0000,布尔型默认是false)课堂练习1:publicclassLocalVariableTest{publicstaticvoidmain(String[]arg){booleanflag=true;//声明boolean型变量并赋值charc1,c2;//声明char型变量c1="u0041";//为char型变量赋值c2="B";//为char型变量赋值intx;//声明int型变量x=9;//为int型变量赋值inty=x;//声明并初始化int型变量floatf=3.15f;//声明float型变量并赋值doubled=3.1415926;//声明double型变量并赋值}331 北京尚学堂科技JAVA基础课程}常量(Constant)·常量:初始化(initialize)后不能再改变值!publicclassConstants{publicstaticvoidmain(String[]args){finaldoublePI=3.14;//PI=3.15;//errordoubler=4;doublearea=PI*r*r;doublecircle=2*PI*r;System.out.println("area="+area);System.out.println("circle="+circle);}}命名规则(规范)1.所有变量、方法、类名:见名知意2.类成员变量:首字母小写和驼峰原则:monthSalary3.局部变量:首字母小写和驼峰原则4.常量:大写字母和下划线:MAX_VALUE5.类名:首字母大写和驼峰原则:Man,GoodMan6.方法名:首字母小写和驼峰原则:run(),runRun()331 北京尚学堂科技JAVA基础课程基本数据类型(primitivedatatype)üJava是一种强类型语言,每个变量都必须声明其类型。üJava的数据类型分为两大类:基本类型(primitivetype)和引用类型(referencetype)üJava中定义了3类8种基本数据类型q逻辑型-booleanq文本型-charq数值型-byte,short,int,long,float,double注:引用数据类型的大小统一为4个字节,记录的是其引用对象的地址!整型变量整型用于表示没有小数部分的数值,它允许是负数。整型的范围与运行Java代码的机器无关,这正是Java程序具有很强移植能力的原因之一。于此相反,C和C++程序需要针对不同的处理器选择最有效的整形。类型占用存储空间表数范围Byte1字节-128~127331 北京尚学堂科技JAVA基础课程Short2字节-215~215-1(-32768~32767)Int4字节-231~231-1(-2147483648~2147483647)约21亿Long8字节-263~263-1üJava语言整型常数的三种表示形式:q十进制整数,如:99,-500,0。q八进制整数,要求以0开头,如:015。q十六进制数,要求0x或0X开头,如:0x15。üJava语言的整型常数默认为int型,声明long型常量可以后加‘l’或‘L’默认的整数类型是int型,要想使用长整型可在后面加“l”或“L”,如:1000L。(小写l容易被误认为1,不推荐用),如:longa=55555555;//不出错,在Int表示的范围内(21亿内)。longb=55555555555;//不加l出错,已经超过int表示的范围。报错:Theliteral55555555555oftypeintisoutofrangeüJava中没有无符号类型浮点型类型占用存储空间表数范围Float4字节-3.403E38~3.403E38Double8字节-1.798E308~1.798E308üfloat类型又被称作单精度类型,尾数可以精确到7位有效数字,在很多情况下,float类型的精度很难满足需求。üdouble表示这种类型的数值精度是float类型的两倍,又被称作双精度,绝大部分应用程序都采用double类型。üJava浮点类型常量有两种表示形式331 北京尚学堂科技JAVA基础课程ü十进制数形式,例如:3.14314.00.314ü科学记数法形式,如314e2314E2314E-2doublef=314e2;//314*10^2-->31400.0doublef2=314e-2;//314*10^(-2)-->3.14üFloat类型的数值有一个后缀F/f,没有后缀F/f的浮点数值默认为double类型。也可以在浮点数值后添加后缀D/d,以明确其为double类型:浮点类型float,double的数据不适合在不容许舍入误差的金融计算领域。    如果需要进行不产生舍入误差的精确数字计算,需要使用BigDecimal类。注:     主要理由:由于字长有限,浮点数能够精确表示的数是有限的,因而也是离散的。浮点数一般都存在舍入误差,很多数字无法精确表示(例如0.1),其结果只能是接近, 但不等于。二进制浮点数不能精确的表示0.1,0.01,0.001这样10的负次幂。并不是所有的小数都能可以精确的用二进制浮点数表示。最好完全避免使用浮点数比较:floatf=0.1f;doubled=1.0/10;System.out.println(f==d);//falsefloatd1=423432423f;floatd2=d1+1;if(d1==d2记住:浮点数不要用于比较。由于其是近似存储,值越大,精度损失越大,越不精确!){System.out.println("d1==d2");331 北京尚学堂科技JAVA基础课程}else{System.out.println("d1!=d2");}大数值:Java.math下面的两个有用的类:BigInteger和BigDecimal,这两个类可以处理任意长度的数值。BigInteger实现了任意精度的整数运算。BigDecimal实现了任意精度的浮点运算。浮点数使用总结:1.默认是double2.浮点数存在舍入误差,很多数字不能精确表示。如果需要进行不产生舍入误差的精确数字计算,需要使用BigDecimal类。3.避免比较中使用浮点数字符型(2个字节):n单引号用来表示字符常量。例如‘A’是一个字符,它与“A”是不同的,“A”表示含有一个字符的字符串。nchar类型用来表示在Unicode编码表中的字符。nUnicode编码被设计用来处理各种语言的所有文字,它占2个字节,可允许有65536个字符;ASCII码占1个字节,可允许有128个字符,是Unicode编码表中前128个字符。chareChar="a";charcChar="中";nUnicode具有从0到65535之间的编码,他们通常用从’u0000’到’uFFFF’之间的十六进制值来表示(前缀为u表示Unicode)charc=‘u0061;nJava语言中还允许使用转义字符‘’来将其后的字符转变为其它的含义,charc2="n";//代表换行符331 北京尚学堂科技JAVA基础课程转义符含义Unicode值b退格(backspace)u0008n换行u000ar回车u000dt制表符(tab)u0009“双引号u0022‘单引号u0027\反斜杠u005c注:以后我们学的String类,其实是字符序列(charsequence)类似于字符数组的概念。boolean类型(一位,不是一个字节):nboolean类型有两个值,true和false,不可以0或非0的整数替代true和false,这点和C语言不同。nboolean类型用来判断逻辑条件,一般用于程序流程控制。booleanflag;flag=………;if(flag){//true分支}else{//false分支}实践:LessisMore!!请不要这样写:if(is==true&&done==false),只有新手才那么写。对于任何程序员if(whether&&!done)都不难理解吧。所以去掉所有的==fasle和==true。331 北京尚学堂科技JAVA基础课程运算符(operator)nJava语言支持如下运算符:q算术运算符:+,-,*,/,%,++,--q赋值运算符=q关系运算符:>,<,>=,<=,==,!=instanceofq逻辑运算符:&&,||,!q位运算符:&,|,^,~,>>,<<,>>>(了解!!!)q条件运算符?:q扩展赋值运算符:+=,-=,*=,/=二元运算符:整数运算:如果两个操作数有一个为Long,则结果也为long没有long时,结果为int。即使操作数全为shot,byte,结果也是int.浮点运算:如果两个操作数有一个为double,则结果为double.只有两个操作数都是float,则结果才为float.提升。各种基本数据类型进行混合运算,结果会是表达能力最强的那种。如:int和long运算,结果是long,整型和浮点型运算结果是浮点型。特殊的一点是:只要类型比int小(如char、byte、short),那么在运算之前,这些值会自动地转换成int。例子:byteb1=12;byteb2=b1+1;//在编译时出错了!因为b1+1已经是int型了!切记!z取模运算:其操作数可以为浮点数,一般使用整数。如:5.9%3.9=2.000000004要点: 负数%负数=负数; 负数%正数=负数; 正数%负数=正数;注:一般都是正整数运算,不用考虑这么细!331 北京尚学堂科技JAVA基础课程一元运算符(++,--):inta=3;intb=a++;//执行完后,b=3。先给b赋值,再自增。intc=++a;//执行完后,c=5。先自增,再给b赋值注意:java中的乘幂处理:inta=3^2;//java中不能这么处理,^是异或符号。doubleb=Math.pow(3,2);Math类提供了很多科学和工程计算需要的方法和常数。布尔逻辑表达符:逻辑与:&&和&,逻辑或:||和|,逻辑非:!。逻辑与和逻辑或采用短路的方式。从左到右计算,如果确定值则不会再计算下去。逻辑与只要有一个为false,则直接返回false.逻辑或只要有一个为true,则直接返回true;booleanc=1>2&&&&不会抛异常;说明没有执行3/0;2>(3/0);位运算符:(了解)~--取反&--按位与|--按位或^--按位异或<<:左移运算符,>>:右移运算符>>>:无符号移位运算符右移一位相当于除2取商。左移一位相当于乘2。inta=3*2*2;intb=3<<2;//相当于:3*2*2;331 北京尚学堂科技JAVA基础课程inta=12/2/2;intb=12>>2;扩展运算符运算符用法举例等效的表达式+=a+=ba=a+b-=a-=ba=a-b*=a*=ba=a*b/=a/=ba=a/b%=a%=ba=a%b字符串连接符:³“+”运算符两侧的操作数中只要有一个是字符串(String)类型,系统会自动将另一个操作数转换为字符串然后再进行连接。intc=12;System.out.println("c="+c);三目条件运算符l三目条件运算符,语法格式:x?y:z经常用来代替简单的if-else判断!l其中x为boolean类型表达式,先计算x的值,若为true,则整个三目运算的结果为表达式y的值,否则整个运算结果为表达式z的值。l举例:intscore=80;intx=-100;Stringtype=score<60?"不及格":"及格";intflag=x>0?1:(x==0?0:-1);System.out.println("type="+type);331 北京尚学堂科技JAVA基础课程System.out.println("flag="+flag);运算符优先级的问题RtoL.(){};,++--~!(datatype)LtoR*/%LtoR+-LtoR<<>>>>>LtoR<><=>=instanceofLtoR==!=LtoR&LtoR^LtoR|LtoR&&LtoR||RtoL?:RtoL=*=/=%=+=-=<<=>>=>>>=&=^=|=大家不需要去刻意的记住他,表达式里面优先使用小括号来组织!!自动类型转换:n自动类型转换:容量小的数据类型可以自动转换为容量大的数据类型。在图中,黑色的实线表示无数据丢失的自动类型转换,而红色的虚线表示在转换时可能会精度的损失。n特例:可以将整型常量直接赋值给byte,short,char等类型变量,而不需要进行强制类型转换,只要不超出其表数范围qShortb=12;//合法331 北京尚学堂科技JAVA基础课程qshortb=1234567;//非法n强制类型转换(Cast):强制类型转换,又被称为造型,用于显式的转换一个数值的类型.在有可能丢失信息的情况下进行的转换是通过造型来完成的,但可能造成精度降低或溢出。n强制类型转换的语法格式:“(type)var”,运算符“()”中的type表示将值var想要转换成的目标数据类型。例如:doublex=3.14;intnx=(int)x;//值为3charc="a";intd=c+1;System.out.println(d);System.out.println((char)d);n当将一种类型强制转换成另一种类型,而又超出了目标类型的表示范围,就会被截断成为一个完全不同的值。例如:intx=300;bytebx=(byte)x;//值为44n不能在布尔类型和任何数值类型之间做强制类型转换。q如果需要把布尔类型转换成一个数字该怎么办呢?使用三木运算符:Booleanb=true;Inta=(b)?1:0;基本类型转化时常见错误和问题:1.操作比较大的数时,要留意是否溢出,尤其是整数操作时。intmoney=1000000000;//10亿331 北京尚学堂科技JAVA基础课程intyears=20;inttotal=money*years;//返回的是负数longtotal1=money*years;//返回的仍然是负数。默认是int,因此结果会转成int值,再转成long。但是已经发生了数据丢失longtotal2=money*((long)years);//先将一个因子变成long,整个表达式发生提升。全部用long来计算。1.L和l的问题:1.不要命名名字为l的变量2.long类型使用大写L不要用小写。intl=2;longa=23451l;System.out.println(l+1);方法lJava的方法类似于其它语言的函数,是一段用来完成特定功能的代码片段,声明格式:[修饰符1修饰符2…]返回值类型方法名(形式参数列表){Java语句;………}l形式参数:在方法被调用时用于接收外界输入的数据。l实参:调用方法时实际传给方法的数据。l返回值:方法在执行完毕后返还给调用它的环境的数据。l返回值类型:事先约定的返回值的数据类型,如无返回值,必须给出返回值类型void。lJava语言中使用下述形式调用方法:对象名.方法名(实参列表)l实参的数目、数据类型和次序必须和所调用方法声明的形参列表匹配,lreturn语句终止方法的运行并指定要返回的数据。lJava中进行方法调用中传递参数时,遵循值传递的原则:331 北京尚学堂科技JAVA基础课程基本类型传递的是该数据值本身。引用类型传递的是对对象的引用,而不是对象本身。lJAVA中只有值传递!简单的键盘输入和输出简单的读取键盘输入的字符串示例:Scannerscanner=newScanner(System.in);//Stringstring=scanner.nextLine();//将输入的一行付给string//Stringstring=scanner.next();//将输入单词到第一个空白符包含:换行符/制表符/空格为止的字符串付给stringintstring=scanner.nextInt();//将输入的数字付给变量System.out.println(string);本章思考作业1.写出JAVA的常用注释方式2.标识符的基本规则3.结合驼峰原则,写出变量、类、方法的命名规则4.写出八种基本数据类型、存储空间、表数范围5.&&和&的区别6.3*8最快的运算方式是什么?7.“+”在什么条件下变成字符串连接符?8.如何实现显式数据类型转换?并举例说明上机操作1.完成课堂上老师的代码!2.结合每个知识点,做上机测试!3.编程计算:一个人的心脏每分钟跳动70次,活了70年,问一共跳动多少次?331 北京尚学堂科技JAVA基础课程第二章(2)控制语句从结构化程序设计角度出发,程序有三种结构:顺序结构331 北京尚学堂科技JAVA基础课程JAVA的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行顺序结构是最简单的算法结构,语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的,它是任何一个算法都离不开的一种基本算法结构。顺序结构在程序流程图中的体现就是用流程线将程序框自上而地连接起来,按顺序执行算法步骤。选择结构if单选择结构如果条件为true执行一个操作:意义:if语句对条件表达式进行一次测试,若测试为真,则执行下面的语句,否则跳过该语句doublei=6*Math.random();doublej=6*Math.random();doublek=6*Math.random();intcount=(int)(i+j+k);if(count>15要求必须是布尔表达式){System.out.println("今天手气不错");}if(count>=10&&count<=15){//错误写法:10=circle){System.out.println("面积大于等于周长");}else{System.out.println("周长大于面积");}If-elseif-else多选择结构if(布尔表达式1){语句块1;}elseif(布尔表达式2){语句块2;}………elseif(布尔表达式n){语句块n;}else{语句块n+1;}331 北京尚学堂科技JAVA基础课程逐条if语句进行判断条件匹配,进入语句体否则对if语句继续匹配publicclassIfTest3{publicstaticvoidmain(String[]args){intage=(int)(100*Math.random());System.out.print("年龄是"+age+",属于");if(age<15){System.out.println("儿童,喜欢玩!");}elseif(age<25){System.out.println("青年,要学习!");}elseif(age<45){System.out.println("中年,要工作!");}elseif(age<65){System.out.println("中老年,要补钙!");}elseif(age<85){System.out.println("老年,多运动!");}else{System.out.println("老寿星,古来稀!");}}}作业:1.仿照例程IfTest3,实现如下功能:随机生成一个100以内的成绩,当成绩在85及以上的时候输出”等级A”,70以上到84之间输出”等级B”,60到69之间输出”等级C”,60以下输出”等级D”.331 北京尚学堂科技JAVA基础课程switch多选择结构根据表达式值的不同执行许多不同的操作Switch语句:case标签必须是整数或者枚举,不能是字符串。根据表达式的值,从一系列代码选出一段执行。格式如下:switch(表达式)byte,char,short,int或枚举类型{case值1case子句中的值必须是常量,且所有case子句中的值应是不同的;:语句序列;[break];case值2:语句序列;[break]每个case都应该以一个break结尾。这样在执行完一个case分支后使程序跳出switch语句块。这是构建switch语句的一种传统方式,尽管break是可选的。;……………[default:默认语句可选;]}switch语句会根据表达式的值从相匹配的case标签处开始执行,一直执行到break语句处或者是switch语句的末尾。与任一case值不匹配,则进入default语句(如果有的话)publicclassVowelsAndConsonants{publicstaticvoidmain(String[]args){charc="a";intrand=(int)(26*Math.random());charc2=(char)(c+rand);System.out.print(c2+":");switch(c2){case"a":331 北京尚学堂科技JAVA基础课程case"e":case"i":case"o":case"u":System.out.println("元音");break;case"y":case"w":System.out.println("半元音");break;default:System.out.println("辅音");}}}作业:n根据输入的月份,打出该月份的天数(不需要考虑润年、闰月)System.out.print("请输入月份:");intmonth=(int)(1+Math.random()*12);if(month>0&&month<13){switch(month){case2:System.out.println("28天");break;case4:case6:case9:case11:System.out.println("30天");331 北京尚学堂科技JAVA基础课程break;default:System.out.println("31天");}//31:1,3,5,7,8,10,1230:4,6,9,1128:2}else{System.out.println("您输入的月份不合法!");}n编写程序实现下述功能:从键盘输入成绩赋给score,然后使用switch语句判断:若为[90,100]则输出“优秀”;若为[80,89]则输出“良好”;若为[70,79]则输出“一般”;若为[60,69]则输出“及格”;若为[0,59]则输出“拜访名师,请其指点!”提示:switch一般用来做多值的判断,如果为条件为区间则最好使用ifelse来做。当然,也可以通过某些计算将区间变通为多值的判断。(了解!!!)intscore=(int)(Math.random()*100);if(score>=0&&score<=100){switch(score/10){case10:case9:System.out.println("成绩优秀!");break;case8:System.out.println("成绩良好!");break;case7:331 北京尚学堂科技JAVA基础课程System.out.println("成绩一般!");break;case6:System.out.println("成绩合格!");break;default:System.out.println("不及格,寻访名师指点!");}}else{System.out.printf条件运算符有时候可用于代替if/else:inta=2;intb=3;if(a0;i--){System.out.println(i);}for(inti=90;i>0;i-=3){System.out.println(i);}}}n(了解!!!)Java里唯一用到逗号运算符的地方就是for循环的控制表达式。在控制表达式的初始化和步进控制部分,我们可以使用一系列由逗号分隔的表达式。而且那些表达式均会独立执行。例如:publicstaticvoidmain(String[]args){for(inti=1,j=i+10;i<5;i++,j=i*2){System.out.println("i="+i+"j="+j);}1.无论在初始化还是在步进部分,语句都是顺序执行的。2.尽管初始化部分可设置任意数量的定义,但都属于同一类型。3.约定:只在for语句的控制表达式中写入进行初始化,测试和修改同一计数器变量的表达式。n初始化部分、条件判断部分和迭代因子可以为空语句,但以“;”分开,下面的语句表示无限循环for(;;){//infiniteloopwhile(true)...}n在for语句的初始化部分声明的变量,其作用域为整个for循环体,例如:for(inti=1;i<10;i++){……331 北京尚学堂科技JAVA基础课程}//inolongerdefinedheren嵌套循环:指的是在一个循环语句内部再嵌套一循环或多个循环。n应用举例publicclassLoopForTest{publicstaticvoidmain(Stringargs[]){for(inti=1;i<=5;i++){for(intj=1;j<=5;j++){System.out.print(i+"");}}}}packagechuji;331 北京尚学堂科技JAVA基础课程publicclassAppMain{publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubAppMainappMain=newAppMain();appMain.addFactorial();}/***计算100之内奇数和偶数的和*/voidcaculate(){intsumOdd=0;//奇数的和intsumEven=0;//偶数的和for(inti=0;i<100;i++){if(i%2==0){sumEven+=i;}else{sumOdd+=i;}}System.err.println("100之内偶数的和:"+sumEven);System.err.println("100之内奇数的和:"+sumOdd);}/**用循环结构输出1000之内所有被5整除的数,并且每行最多输出3个*/voidtest2(){inti=0;331 北京尚学堂科技JAVA基础课程intj=0;while(i<1000){if(i%5==0){System.out.print(i+"t");j++;if(j%3==0){System.out.print("n");j=0;}}i++;}}/***输出九九乘法表*/voidmultiplicationTable(){for(inti=1;i<10;i++){//i是一个乘数for(intj=1;j<=i;j++){//j是另一个乘数System.out.print(j+"*"+i+"="+(i*j<10?(""+i*j):i*j)+"");}System.out.println();}}/**331 北京尚学堂科技JAVA基础课程*编程求:1+(1+2)+(1+2+3)+...+(1+2+...+100)*/voidaddAdd(){intsum=0;//总和for(inti=1;i<=100;i++){inttempSum=0;//临时和for(intj=1;j<=i;j++){tempSum+=j;}sum+=tempSum;}System.out.println(sum);}/***编程求:1!+2!+。。。+15!*/voidaddFactorial(){longresult=0;for(inti=1;i<=15;i++){inttemp=1;for(intj=1;j<=i;j++){temp*=j;}result+=temp;}System.out.println(result);}331 北京尚学堂科技JAVA基础课程}练习2:输入一个字符串,统计大写字母、小写字母的个数:publicstaticvoidmain(String[]args){Stringstr="sdklfjdsfSDJFDLF;DSFsdfjdsfdsf";intlowerNum=0;intupperNum=0;for(inti=0;i="a"&&c<="z"){lowerNum++;}if(c>="A"&&c<="Z"){upperNum++;}}System.out.printf("大写字母个数:%d",upperNum);System.out.printf("小写字母个数:%d",lowerNum);}这三种基本逻辑结构是相互支撑的,它们共同构成了算法的基本结构,无论怎样复杂的逻辑结构,都可以通过这三种结构来表达上述三种结构组成的程序可以解决全部的问题,所以任何一种高级语言都具备上述三种结构。331 北京尚学堂科技JAVA基础课程break语句和continue语句n在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。(break语句还可用于多支语句switch中,在后述中)publicclassBreakTest{publicstaticvoidmain(String[]args){inttotal=0;System.out.println("Begin");while(true){total++;inti=(int)Math.round(100*Math.random());if(i==88)break;}System.out.println("Gameover,used"+total+"times.");}}n无限循环的第二种形式是for(;;)。编译器将while(true)与for(;;)看作同一回事。ncontinue语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。n用在while,do-while中,continue语句立刻跳到循环首部,越过了当前循环的其余部分。n用在for循环中,跳到for循环的迭代因子部分。把100~150之间不能被3整除的数输出:publicclassContinueTest{publicstaticvoidmain(String[]args){for(inti=100;i<150;i++){if(i%3==0)continue;331 北京尚学堂科技JAVA基础课程System.out.println(i);}}}带标签的break&continue在java语句里,唯一能放标签的地方是在循环语句前面。而且循环语句跟标签之间不能有任何东西。:(了解!!!)ngoto关键字很早就在程序设计语言中出现。尽管goto仍是Java的一个保留字,但并未在语言中得到正式使用;Java没有goto。然而,在break和continue这两个关键字的身上,我们仍然能看出一些goto的影子---带标签的break和continue。n“标签”是指后面跟一个冒号的标识符,例如:label:n对Java来说唯一用到标签的地方是在循环语句之前。而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方。例如:label1:外部循环{内部循环{//...break;//...continue;//...continuelabel1;//...breaklabel1;}}带标签的break和continue的例子:publicclassPrimeNumber{//打印101-150之间所有的质数publicstaticvoidmain(Stringargs[]){intcount=0;outer:for(inti=101;i<150;i++){for(intj=2;j1){result*=a*(a-1);a-=2;}longd4=System.currentTimeMillis();System.out.println(result);System.out.printf("普通循环费时:%s%n",d4-d3);//结果为0.注意:任何可用递归解决的问题也能使用迭代解决。当递归方法可以更加自然地反映问题,并且易于理解和调试,并且不强调效率问题时,可以采用递归;331 北京尚学堂科技JAVA基础课程在要求高性能的情况下尽量避免使用递归,递归调用既花时间又耗内存。本章作业1.break和continue的区别2.while和dowhile的区别3.switch语句开始执行,进入某个case语句后,什么时候结束?4.什么时候使用ifelseif…else?什么时候使用swtich?本章上机操作1.完成老师课堂上所有代码,及本文档中列出的所有代码!2.使用递归完成阶乘算法!331 北京尚学堂科技JAVA基础课程331 北京尚学堂科技JAVA基础课程第三章JAVA面向对象程序开发编程语言发展史见第一章相关内容。计算机语言发展的主线:随着计算机深入人们的生活,所要解决的问题越来越复杂,同时计算机运行速度越来越快,问题的解决更大程度上指的是问题本身而不是解决问题的效率,为了适应这种需求,计算机语言越来越向方便人类思考问题的方向发展。类和对象是如何产生发展的?如何进化的?最初的计算机语言只有基本变量(类似我们学习的基本数据类型),用来保持数据。但是数据多了怎么办?成千上万的数据怎么处理?于是有了数组的概念,通过数组将这同类型的数组进行组织。后来,数据不仅多了而且复杂了怎么办?数组只能存放同类型的数据,于是产生了结构体(c/c++中的struct),可以将不同类型的数据包括在一个数据结构。后来,数据不仅多了,复杂了,而且对数据的操作(指的就是方法)也多了复杂了,怎么办?结构体只包含了数据,没有包含对数据操作的方法。即,数据和方法是分离的,虽然他们联系紧密但是各自为政。于是,类和对象产生了。说白了,对象也是一种数据结构而已。包含了:不同的数据类型(属性field)和相关的操作处理(方法method)。面向过程:数据和方法是分离的。面向对象:数据和方法集成到一起,便于扩展。类和对象进化史人类政府进化史抽象类比数据少时基本类型数据阶段人少时群居时代无管理时代(对数据或人没有任何管理)数据多了人多了弱管理时代(将同类型数据集中进行管理)331 北京尚学堂科技JAVA基础课程数组产生,可以存放管理同类型数据部族产生,血缘关系一样的在一个部族数据多了,数据之间关系复杂了结构体产生人多了,不同血缘关系的人多了,关系复杂了产生部落,将不同类型的人集合到一起强管理时代(将不同类型数据/不同血缘关系人集中管理)数据多了数据关系复杂数据的操作复杂了产生类和对象将数据和相关的操作行为放到一起人多了,关系复杂了,每个人的行为也复杂了于是,产生政府。不仅包含人、而且包含管理人的行为。超强管理时代(将数据和数据操作/人和人的行为放到一起管理)总结:类和对象说白了也是一种数据结构(对数据的管理模式),将数据和数据的行为放到了一起。在内存上,对象就是一个内存块,存放了相关的数据集合!类和对象就是一种数据的组织方式!面向对象思想初步(OOP初步ObjectOrientedProgramming)面向对象和面向过程思想的区别和联系深入掌握面向对象思维方式思考问题面向对象和面向过程详解我们常说高级语言分为:面向过程和面向对象。面向过程:c面向对象:c++,Java共同点:面向过程和面向对象都是解决实际问题的一种具体思路。区别:大家描述一下如下两件事儿:331 北京尚学堂科技JAVA基础课程如何开汽车(事物比较简单,可以用线性的思维去解决)面向过程:1.采离合2.挂档3.踩油门,放离合4.开了面向对象:驾驶员2.汽车驾驶员开汽车!Motor.start();如何造汽车(事物比较复杂,使用简单的线性思维无法解决)面向过程:1.造车轮2.造发动机3.造车皮4.挡风玻璃…面向对象:车轮买橡胶到马来西亚买飞机票找到橡胶厂掏钱买用船将橡胶运到国内造磨具将橡胶放入磨具出车轮发动机….车壳….座椅…挡风玻璃….将上面的造出的东东,组装,汽车造出!331 北京尚学堂科技JAVA基础课程对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,可能需要面向过程的思路去处理。蒋介石为什么败给毛主席?蒋介石和毛主席同样要做一件事:统一中国!蒋介石的错误就在于把这样一件复杂的事情、一件系统工程,当作了一件简单的事情来做:他的想法很简单,依靠自己强大的军队、打内战,赢内战,统一中国。他把统一中国简单的看做让国民党军队击败共产党军队。所以,思维短路,战略也很简单:面向过程:抢占战败日本的物资,收编伪军,拉美国的金援。和共产党谈判,拖延时间,为战争准备争取时间抢占城市等战略要点开打!赢!哦耶!整个战略里面,没有农民、没有工人、军队之间派系关系、美国、苏联等等。所有这些重要的对象。这样简单的战略方式,遇到普通对手可能还能凑合用。遇到老毛,面向过程VS面向对象。毛主席是面向对象思考的。毛主席的战略(解放战争三大法宝:党的建设、武装斗争、群众路线):共产党(加强党的建设、增强凝聚力战斗力)农民贫农中农富农用统一战线战略来处理这些对象的关系工人地主知识分子331 北京尚学堂科技JAVA基础课程国民党进步派中间派反动派各民主派别毛主席的战略不是简单的军事方针,而是一整套的政治战略。将统一中国这种复杂的问题,归结为一个核心,主要矛盾:中国人民和美帝国主义支持下的国民党反动派的矛盾。说白了,就是共产党带领全国人民和国民党反动派进行斗争。武装斗争是手段,党的建设和统一战线解放战争三大法宝!才是解放战争最重要的根基!毛主席战略思想核心就是:“团结多数打击少数!”,团结的手段很多:增强自身先进性,自己没有魅力怎么团结人?通过打击少数给多数以好处。所以,从战略上有武装斗争、统一战线、党的建设。从具体战术上也有“集中优势兵力,消灭敌人有生力量!”。毛主席军事思想核心:“集中优势兵力,消灭敌人有生力量”。说白话一点,就是“以自己的长处碰对手的短处”。这个大家可以从毛主席的十大军事原则中看出,国民党哪里弱就打哪里,农村和小城市力量小,就先打农村小城市。分散孤立的敌人力量小,就先消灭他们。再加上辩证法,通过我方的斗争,对手战略上的优势可以转化成劣势,我们战略上的劣势可以转化成优势。国民党占领大城市是个巨大的优势,但是通过我们的游击战反而让他感觉变成了包袱。总体上没有国民党军队强大没关系,但是我们要保证每一场仗,都能集中优势兵力,局部形成优势消灭敌人有生力量。一场场仗打下来,量变引起质变,最终在总体上超过对手。我自己总结了一句话,老毛第一用善于用面向对象思维宏观上把握问题的关键,第二善于微观上面向过程解决问题。让微观服务于宏观。331 北京尚学堂科技JAVA基础课程具体流程就是,先把需要处理的对象搞出来,然后处理对象之间的关系,处理关系的方式就是老毛的各种思想。我总结老毛的思想:“战略上团结多数,战术上打击少数,辩证思考问题。”现实生活中,一切问题归根结底是人的问题,人也是对象,所以我们经常说:搞对象。JAVA世界里,一切问题归根结底是对象的问题。我们思考解决问题的方案,首先就是要把对象搞出来。然后再去思考具体的细节。最后再说一句话,毛主席要来学java的话,绝对是最好的架构师。蒋介石来学java的话,最多也就是高级程序员。希望大家举一反三,无论是在现实生活中,还是在软件编码中,都要时时刻刻以面向对象的思维宏观上处理好系统问题。面向对象和面向过程的总结:都是解决问题的思维方式,都是代码组织的方式。解决简单问题可以使用面向过程解决复杂问题:宏观上使用面向对象把握,微观处理上仍然是面向过程。面向对象思考方式:遇到复杂问题,先从问题中找名词,然后确立这些名词哪些可以作为类,再根据问题需求确定的类的属性和方法,确定类之间的关系。面向对象编程的语言的三大特征简介隐藏/封装(encapsulation,capsul胶囊)需要让用户知道的暴露出来,不需要让用户了解的全部隐藏起来。这就是封装。“该露的露,该藏的藏。”继承(extend)继承的本质是对某一批类的抽象抽象就是抽出像的部分”,看似调侃,实乃至理,从而实现对现实世界更好的建模。331 北京尚学堂科技JAVA基础课程继承的另一个好处是:代码重用,让我们不再重新发明轮子(don’treinventwheels)多态(polymorphism)为了处理问题的灵活性。就是在做之前,不要把话说死,说的模糊一点想象空间大一点,真做的时候再具体化。对象和类的概念首先,我们需要考虑一个问题“为什么叫做面向对象,而不是面向类?”。计算机语言越到高级越接近人的思维方式,这是语言发展的一个基本规律。我们人认识世界,其实就是面向对象的。大家眼里都是一个个对象,要不怎么老说搞对象搞对象啊。比如现在让大家认识一下“天使”这个新事物,天使大家没见过吧,怎么样认识呢?最好的办法就是,给你们面前摆10个天使,带翅膀的美女,让大家看,看完以后,即使我不说,大家下一次是不是就都认识天使了。但是,看完10个天使后,我们总要总结一下,什么样的东东才算天使?天使是无数的,总有没见过的!所以必须总结抽象,便于认识未知事物!总结的过程就是抽象的过程。小时候,我们学自然数时怎么定义的?像1,2,3,4…这样的数就叫做自然数。通过抽象,我们发现天使有这样一下特征:带翅膀(带翅膀不一定是天使,还可能是鸟人)女孩(天使掉下来脸着地,也是天使!)善良头上有光环那么通过这10个具体的天使,我们进行抽象,抽象出了天使的特征,我们也可以归纳一个天使类。通过这个过程,类就是对象的抽象,对象的集合。很多时候,考虑类就是考虑对象,区别不大。总结:对象:是具体的事物类:是对对象的抽象天使是上帝搞出来的,对不?在软件世界里,程序员就是上帝!对象是有我们new出来。类可以看做是一个模版,或者图纸,系统根据类的定义来造出对象。我们要造一个汽车,怎么样造?类就是这个图纸,规定了汽车的详细信息,然后根据图纸将汽车造出来。331 北京尚学堂科技JAVA基础课程对象和类的关系:特殊到一般,具体到抽象。类:我们叫做class。对象:我们叫做Object,instance(实例)。以后我们说某个类的对象,某个类的实例。是一样的意思。³类可以看成一类对象的模板,对象可以看成该类的一个具体实例。³类是用于描述同一类形的对象的一个抽象的概念,类中定义了这一类对象所应具有的静态和动态属性。³对象是Java程序的核心,在Java程序中“万事万物皆对象”。³J2SDK提供了很多类供编程人员使用,编程人员也可定义自己的类。类和对象初步测试类的定义方式publicclassCar{//每一个源文件必须有且只有一个publicclass,并且类名和文件名保持一致!}classTyre类名通常首字母大写{//一个java文件可以同时定义多个class}classEngine{331 北京尚学堂科技JAVA基础课程}classSeat{}上面的类定义好后,没有任何的其他信息,就跟我们拿到一张张图纸,但是纸上没有任何信息,这是一个空类,没有任何实际意义。所以,我们需要定义类的具体信息。对于一个类来说,一般有三种常见的成员:属性field、方法method、构造器constructor??。这三种成员都可以定义零个或多个。简单的学生类编写示例publicclassSxtStu{//fieldintid;Stringsname;intage;Computercomp;voidstudy(){System.out.println("我正在学习!");}SxtStu(){}publicstaticvoidmain(String[]args){SxtStustu1=newSxtStu();stu1.sname="张三";Computercomp1=newComputer();331 北京尚学堂科技JAVA基础课程comp1.cpu=”amd”;Computercomp2=newComputer();comp2.cpu=”amd”;stu1.comp=comp1;SxtStustu2=newSxtStu();stu2.sname="李四";stu1.study();}}classComputer{Stringkeyboard;Stringmainboard;Stringmouse;Stringcpu;Stringmonitor;}内存分析栈:1.每个线程私有,不能实现线程间的共享!2.局部变量放置于栈中。3.栈是由系统自动分配,速度快!栈是一个连续的内存空间!331 北京尚学堂科技JAVA基础课程堆:1.放置new出来的对象!2.堆是一个不连续的内存空间,分配灵活,速度慢!方法区:1.被所有线程共享!2.用来存放程序中永远是不变或唯一的内容。(类代码信息、静态变量、字符串常量)属性(field,或者叫成员变量)属性用于定义该类或该类对象包含的数据或者说静态属性。属性作用范围是整个类体在定义成员变量时可以对其初始化,如果不对其初始化,Java使用默认的值对其初始化。(数值:0,0.0char:u0000,boolean:false,所有引用类型:null)属性定义格式:331 北京尚学堂科技JAVA基础课程[修饰符]可以省略。可以是:public,protected,privateStatic,final。讲到隐藏和封装时再说。属性类型可以是任何类型,基本类型和引用类型属性名合法标识符即可。首字母小写,驼峰原则!=[默认值]引用类型ØJava语言中除基本类型之外的变量类型都称之为引用类型。ØJava中的对象是通过引用对其操作的.类的方法方法则用于定义该类或该类的实例的行为特征和功能实现。方法是类和对象行为特征的抽象。方法很类似于面向过程中的函数。面向过程中,函数是最基本单位,整个程序有一个个函数调用组成;面向对象中,整个程序的基本单位是类,方法是从属于类的。方法定义格式:[修饰符]可省略。也可以是:public,protected,private,static,final,abstract方法返回值类型void无返回值。其他类型即可。方法名(形参列表){//n条语句}对象的创建和使用³必须使用new关键字创建对象。²Personperson=newPerson();³使用对象(引用).成员变量来引用对象的成员变量。²person.age³使用对象(引用).方法(参数列表)来调用对象的方法。²person.setAge(23)³同一类的每个对象有不同的成员变量存储空间。³同一类的每个对象共享该类的方法。331 北京尚学堂科技JAVA基础课程构造器(或者叫做构造方法,constructor)构造器用于构造该类的实例。Java通过new关键字来调用构造器,从而返回该类的实例。是一种特殊的方法:格式如下:[修饰符]可以省略。可以是:public,protected,private类名构造器名和类名必须保持一致(形参列表){//n条语句}要点:通过new关键字调用!!构造器虽然有返回值,但是不能定义返回类型(返回值的类型肯定是本类),不能在构造器里调用return。如果我们没有定义构造器,则系统会自动定义一个无参的构造函数。如果已定义则编译器不会添加!构造器的方法名必须和类名一致!构造函数不是没有返回值吗?为什么不能用void?规定。事实上,构造函数是有返回值的就是构造的对象。如此写法只是针对构造函数的特殊规定。课堂作业:³定义一个“点”(Point)类用来表示三维空间中的点(有三个坐标)。要求如下:²可以生成具有特定坐标的点对象。²提供可以设置三个坐标的方法。²提供可以计算该“点”距另外点距离平方的方法。classPoint{doublex,y,z;331 北京尚学堂科技JAVA基础课程publicPoint(double_x,double_y,double_z){x=_x;y=_y;z=_z;}publicdoublegetDistance(Pointp){returnMath.sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y)+(z-p.z)*(z-p.z));}}classTest{publicstaticvoidmain(String[]args){Pointp=newPoint(5.0,6.0,7.8);Pointorigin=newPoint(0.0,0.0,0.0);System.out.println(p.getDistance(origin));}}课下作业³设计一个类代表二维空间的一个点³设计一个类代表二维空间的一个圆。要求两个成员变量。一个是圆心,一个是半径³提供计算面积的方法。³为上述Cricle类添加一个方法,计算一个点(Point对象)是否在圆(Cricle对象)内,并写程序验证。classPoint{doublex;331 北京尚学堂科技JAVA基础课程doubley;Point(doublex1,doubley1){x=x1;y=y1;}publicbooleancontainedBy(Circlec){returnc.contains(this);}}classCircle{Pointo;doubleradius;Circle(Pointp,doubler){o=p;radius=r;}Circle(doubler){o=newPoint(0.0,0.0);radius=r;}publicdoublearea(){return3.14*radius*radius;}331 北京尚学堂科技JAVA基础课程publicbooleancontains(Pointp){if((p.x-o.x)*(p.x-o.x)+(p.y-o.y)*(p.y-o.y)<=radius*radius){returntrue;}returnfalse;}}classTest{publicstaticvoidmain(Stringargs[]){Circlec1=newCircle(newPoint(1.0,2.0),2.0);Circlec2=newCircle(5.0);System.out.println("c1:("+c1.o.x+","+c1.o.y+"),"+c1.radius);System.out.println("c2:("+c2.o.x+","+c2.o.y+"),"+c2.radius);System.out.println("c1area="+c1.area());System.out.println("c1area="+c2.area());c1.o.x=5;c1.o.y=6;c2.radius=9.0;System.out.println("c1:("+c1.o.x+","+c1.o.y+"),"+c1.radius);System.out.println("c2:("+c2.o.x+","+c2.o.y+"),"+c2.radius);System.out.println("c1area="+c1.area());331 北京尚学堂科技JAVA基础课程System.out.println("c1area="+c2.area());Circlec=newCircle(newPoint(3.5,6.4),8.0);System.out.println(c.contains(newPoint(7.0,7.0)));}}垃圾回收机制(GarbageCollection)JAVA的内存管理实际上指的就是对象的管理,其中包括对象空间的分配和释放。对象空间的分配:使用new关键字创建对象即可对象空间的释放:将对象赋值null即可。垃圾回收器将负责回收所有”不可达”对象的内存空间。要点:1.程序员无权调用垃圾回收器。2.程序员可以通过System.gc()。通知GC运行,但是JAVA规范并不能保证立刻运行。3.finaliza方法,是JAVA提供给程序员用来释放对象或资源的方法,但是尽量少用。方法的重载(overload),构造方法的重载l方法的重载是指一个类中可以定义有相同的名字,但参数不同的多个方法两同三不同同一个类,同一个方法名,不同:参数列表中类型、个数、顺序不同。调用时,会根据不同的参数表选择对应的方法。l方法调用时,匹配离得最近的类型l不同的含义:类型,个数,顺序不同l只有返回值不同不构成方法的重载(inta(Stringstr){},voida{inti},调用:a(),谁能告诉我是调哪个方法?)l只有形参的名称不同,不构成方法的重载331 北京尚学堂科技JAVA基础课程l与普通方法一样,构造方法也可以重载publicclassHello{inta,b;intadd(inta,intb){returna+b;}/*doubleadd(inta,intb){returna+b;}*/intadd(inta,doubleb){return(int)(a+b);}intadd(doubleb,inta){return(int)(a+b);}intadd(doublea,doubleb){return(int)(a+b);}Hello(){}331 北京尚学堂科技JAVA基础课程Hello(int_a){a=_a;}Hello(int_a,int_b){a=_a;b=_b;}publicstaticvoidmain(String[]args){newHello().add(3,4.5);newHello().add(5.5,6);newHello().add(4,6);}}this关键字普通方法中,this总是指向调用该方法的对象。构造方法中,this总是指向正要初始化的对象。this最常的用法:让类中的一个方法,访问该类的另一个方法或属性。使用this关键字调用重载构造方法。避免相同的初始化代码,只能在构造方法中用,并且必须位于构造方法的第一句。331 北京尚学堂科技JAVA基础课程this不能用于static方法。(讲完static,大家就知道为什么了!)使用示例:publicclassTestThis{inta,b,c;TestThis(){System.out.println("正要new一个Hello对象");}TestThis(inta,intb){//Hello();////这样是无法调用构造方法的!this();//调用无参的构造方法,并且必须位于第一行!a=a;//这里都是指的局部变量而不是成员变量this.a=a;//这样就区分了成员变量和局部变量.这种情况占了this使用情况的大多数!this.b=b;}TestThis(inta,intb,intc){this(a,b);//调用无参的构造方法,并且必须位于第一行!this.c=c;}voidsing(){}331 北京尚学堂科技JAVA基础课程voidchifan(){this.sing();//sing();System.out.println("你妈妈喊你回家吃饭!");}publicstaticvoidmain(String[]args){TestThishi=newTestThis(2,3);hi.chifan();}}static关键字³在类中,用static声明的成员变量为静态成员变量或者叫做:类属性,类变量!从属于类,代表整个类的属性,可以被该类所有对象共享。成员变量从属于对象,生命周期伴随对象生成和消灭.²它为该类的公用变量,属于类,被该类的所有实例共享,在类被载入时被显式初始化,²对于该类的所有对象来说,static成员变量只有一份。被该类的所有对象共享!!²可以使用”对象.类属性”来调用。不过,一般都是用“类名.类属性”。³用static声明的方法为静态方法也成为:类方法。实例方法从属于对象,代表该对象的行为;静态方法从属于类,代表该类的行为,,可以被该类所有对象共享。²不需要对象,就可以调用(类名.方法名)²在调用该方法时,不会将对象的引用传递给它,所以在static方法中不可访问非static的成员。³可以通过对象引用或类名(不需要实例化)访问静态成员。内存分析:331 北京尚学堂科技JAVA基础课程static使用示例:publicclassTestStatic{inta;staticintwidth;staticvoidgg(){System.out.println("gg");}voidtt(){System.out.println("tt");}publicstaticvoidmain(String[]args){TestStatichi=newTestStatic();TestStatic.width=2;TestStatic.gg();//gg();hi.gg();//通过引用也可以访问static变量或static方法。不过,一般还是使用类名.static成员名来访问。331 北京尚学堂科技JAVA基础课程gg();}}静态初始化块(经常用来初始化类,加载类信息时执行!)如果希望加载后,对整个类进行某些初始化操作,可以使用static初始化块。是在类初始化时执行,不是在创建对象时执行。静态初始化块中不能访问非static成员。执行顺序:先不管,等学完继承后,再回头看!上溯到Object类,先执行Object的静态初始化块,再向下执行子类的静态初始化块,直到我们的类的静态初始化块为止。publicclassTestStaticBlock{static{System.out.println("此处,可执行类的初始化工作!");}publicstaticvoidmain(String[]args){System.out.println("main方法中的第一句");}}packagepackage:为什么需要package?331 北京尚学堂科技JAVA基础课程为了解决类之间的重名问题。为了便于管理类:合适的类位于合适的包!package怎么用?通常是类的第一句非注释性语句。包名:域名倒着写即可,再加上模块名,并与内部管理类。其实内部实现就是靠目录结构来做到的。com.sun.testcom.oracle.testcom.bjsxt.gao.testcom.bjsxt.gao.viewcom.bjsxt.gao.view.model注意事项:写项目时都要加包,不要使用默认包。com.gao和com.gao.car,这两个包没有包含关系,是两个完全独立的包。只是逻辑上看起来后者是前者的一部分。增加package后的编译问题:使用:javac-d.指的是当前目录。当然也可以在这里指定其他目录,比如:e:/aa,那么就会在这个目录下生成子目录!Test.java(会自动在当前目录下生成包对应的子目录)javacom.bjsxt.Test,或者javacom/bjsxt/TestJDK中的主要包³java.lang-包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能。³java.awt-包含了构成抽象窗口工具集(abstractwindowtoolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。331 北京尚学堂科技JAVA基础课程³java.net-包含执行与网络相关的操作的类。³java.io-包含能提供多种输入/输出功能的类。³java.util-包含一些实用工具类,如定义系统特性、使用与日期日历相关的函数。import为什么需要import?如果不适用import,我们如果用到其他包的类时,只能这么写:java.util.Date,代码量太大,不利于编写和维护。通过import可以导入其他包下面的类,从而可以在本类中直接通过类名来调用。import怎么使用?importjava.util.Date;importjava.util.*;//导入该包下所有的类。会降低编译速度,但不会降低运行速度。注意要点:java会默认导入java.lang包下所有的类,因此这些类我们可以直接使用。如果导入两个同名的类,只能用包名+类名来显示调用相关类:java.util.Datedate=newjava.util.Date();staticimport静态导入名字起的不好,应该叫:导入静态属性更好。(JDK1.5后增加,了解!!!!):静态导入的作用:用于导入指定类的静态属性如何使用:importstaticjava.lang.Math.*;//导入Math类的所有静态属性importstaticjava.lang.Math.PI;//导入Math类的PI属性然后,我们可以在程序中直接使用:System.out.println(PI);上面两种导入方式都是为了便于编写代码,提高可维护性。331 北京尚学堂科技JAVA基础课程eclipse的使用背景介绍1.eclipse是一个开发平台。不仅开发JAVA,还可以开发C/C++,PHP等等。2.有很多插件.myeclipse等3.www.open-open.com常用操作1.建项目newàJavaProjectà输入项目名称2.建包右键单击srcànewàpackage3.建类newàclass4.视图操作删除视图移动视图增加视图:windowàshowviewàconsole,packageExplore等等5.程序运行:右键单击编辑区àrunasàjavaapplication快捷键:ctrl+F11,alt+shift+x,J6.Debug模式a)加/删除断点:行号双击b)Debugasàjavaapplicationà打开一个对话框,问是否显示debug视图,选择是即可。7.常用快捷键a)命令提示:alt+/(main,syso)b)文件选择:i.Shift+上下左右,home,end键331 北京尚学堂科技JAVA基础课程i.Ctrl+Shift+左右单词选中b)删除一行:ctrl+dc)复制一行到下面或上面:ctrl+alt+上下d)换行:alt+上下e)编辑文件切换:ctrl+F6,或者ctrl+E,上下f)视图切换:ctrl+F7g)查看错误建议:ctrl+1h)导入类:ctrl+shift+oi)重命名:alt+shift+r继承(extend,inheritance)为什么需要继承?继承的作用?第一好处:继承的本质在于抽象继承的存在是有一定历史原因。最初的面向对象语言只有继承没有接口。c++就不直接支持接口。只能通过继承来实现对某一批类的抽象。1.高司令就说过,Gosling,java发明人。有人问“如果你重新构造java,你最想改变什么?”。“我想抛弃classes”,一片笑声,“问题不是class,而是继承,使用接口继承更好。应该尽量避免使用extends继承。”因为,继承失去了灵活性。面向接口编程更加灵活。当然,继承最大的问题是强耦合。这些问题,现在讨论起来可能为时过早。事实上,大家到了公司,或者学到高级框架后,会发现我们的编程往往都是面向接口的编程。。类是对对象的抽象,继承是对某一批类的抽象。第二好处:为了提高代码的复用性。(事实上,利用组合可以更好的实现代码复用!)extands的意思是“扩展”。子类是父类的扩展。继承介绍现实世界中的继承无处不在。比如:动物:哺乳动物、爬行动物哺乳动物:灵长目、鲸目等。继承的本质是对某一批类的抽象抽象就是抽去像的部分”,看似调侃,实乃至理,从而实现对现实世界更好的建模。331 北京尚学堂科技JAVA基础课程如何实现继承?使用extends关键字即可。publicclassTestExtends{publicstaticvoidmain(String[]args){Mammalm1=newMammal();m1.puru();m1.eat();}}classAnimal{Stringeyes="眼睛";Stringname="无名";publicvoideat(){System.out.println("动物吃东西!");}}classMammalextendsAnimal{//哺乳publicvoidpuru(){System.out.println("小动物吃奶!");}}331 北京尚学堂科技JAVA基础课程继承使用要点子类继承父类,可以得到父类的全部属性和方法(除了父类的构造方法)。java中只有单继承意味着,一个类只能有一个直接父类!,没有像c++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难于维护。就像我们现实中,如果你有多个父母亲,那是一个多么混乱的世界啊。多继承,就是为了实现代码的复用性,却引入了复杂性,使得系统类之间的关系混乱。java中的多继承,可以通过接口来实现如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。不同的叫法:超类、父类、基类、子类、派生类父类方法的重写:“==”:方法名、形参列表相同。“≤≤”:返回值类型和异常类型,子类小于等于父类。“≥”:访问权限,子类大于等于父类private成员问题:子类继承父类的一切东西.可以用debug看看。确实有父类的private成员,只不过是不能访问。 中说到, 子类对象拥有父类对象的完整拷贝. 实例化一个类是从最顶级的超类开始实例化的, 是一层一层的包裹结构. private限制访问方式只能在类的内部, 这仅仅是一个访问控制, 实际上子类对象拥有父类对象的一切.子类自己定义的bb和父类私有属性bb,在子类对象中都存在。子类的bb相当于新定义的属性。同理,也使用private方法。属性查找顺序:(比如:查找变量h)查找当前类中有没有属性h依次上溯每个父类,查看每个父类中是否有h,直到Object如果没找到,则出现编译错误。上面步骤,只要找到h变量,则这个过程终止。331 北京尚学堂科技JAVA基础课程构造方法调用顺序:根据super的说明,构造方法第一句不显式调用,系统自动会掉总是:super(…)来调用父类对应的构造方法。先向上追溯到Object,然后再依次向下执行类的初始化块和构造方法,直到当前子类为止。Object类³Object类是所有Java类的根基类³如果在类的声明中未使用extends关键字指明其基类,则默认基类为Object类publicclassPerson{...}³等价于:publicclassPersonextendsObject{...}toString方法³Object类中定义有publicStringtoString()方法,其返回值是String类型,描述当前对象的有关信息。³在进行String与其它类型数据的连接操作时(如:System.out.println(“info”+person)),将自动调用该对象类的toString()方法³可以根据需要在用户自定义类型中重写toString()方法。equals方法先放一边!³Object类中定义有:²publicbooleanequals(Objectobj)方法331 北京尚学堂科技JAVA基础课程±提供定义对象是否“相等”的逻辑。²Object的equals方法定义为:x.equals(y)当x和y是同一个对象的应用时返回true否则返回false²J2SDK提供的一些类,如String,Date等,重写了Object的equals方法,调用这些类的equals方法,x.equals(y),当x和y所引用的对象是同一类对象且属性内容相等时(并不一定是相同对象),返回true否则返回false。²可以根据需要在用户自定义类型中重写equals方法。publicclassTest{publicstaticvoidmain(String[]args){Personp1=newPerson(123,"aa",3);Personp2=newPerson(123,"bbb",3);System.out.println(p1==p2);//falseSystem.out.println(p1.equals(p2));//true}}classPerson{intid;Stringname;intage;publicPerson(intid,Stringname,intage){this.id=id;this.name=name;this.age=age;}publicbooleanequals(Objectobj){if(obj==null){returnfalse;331 北京尚学堂科技JAVA基础课程}else{if(objinstanceofPerson){Personc=(Person)obj;if(c.id==this.id){returntrue;}}}returnfalse;}代码比较典型!希望大家消化一下。不过,以后项目可以自动生成。也不用太紧张!}super关键字super是直接父类对象的引用。可以通过super来访问父类中被子类覆盖的方法或属性。普通方法:没有顺序限制。可以随便调用。构造函数中:任何类的构造函数中,若是构造函数的第一行代码没有显式的调用super(...);那么Java默认都会调用super();作为父类的初始化函数。所以你这里的super();加不加都无所谓。publicclassTest{publicstaticvoidmain(String[]args){newChildClass().f();}}classFatherClass{331 北京尚学堂科技JAVA基础课程publicintvalue;publicvoidf(){value=100;System.out.println("FatherClass.value="+value);}}classChildClassextendsFatherClass{publicintvalue;publicvoidf(){super.f();value=200;System.out.println("ChildClass.value="+value);System.out.println(value);System.out.println(super.value);}}方法的重写(override)³在子类中可以根据需要对从基类中继承来的方法进行重写。³重写方法必须和被重写方法具有相同方法名称、参数列表和返回类型。³重写方法不能使用比被重写方法更严格的访问权限。(由于多态)publicclassTest{publicstaticvoidmain(String[]args){331 北京尚学堂科技JAVA基础课程Animalanimal=newAnimal();animal.shout();Dogdog=newDog();dog.shout();}}classAnimal{voidshout(){System.out.println("发出声音!");}}classDogextendsAnimal{voidshout(){System.out.println("旺旺旺!");}}隐藏/封装(encapsulation)为什么需要封装?封装的作用和含义?我要看电视,只需要按一下开关和换台就可以了。有必要了解电视机内部的结构吗?有必要碰碰显像管吗?我要开车,….制造厂家为了方便我们使用电视,方便我们开车,把复杂的内部细节全部封装起来,只给我们暴露简单的接口,比如:电源开关、比如:油门。具体怎么内部实现的,我们不需要操心。需要让用户知道的暴露出来,不需要让用户了解的全部隐藏起来。这就是封装。331 北京尚学堂科技JAVA基础课程白话:该露的露,该藏的藏专业:我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合程序的一部分对另一部分的依赖关系:仅暴露少量的方法给外部使用。编程中封装的具体意义:便于调用者调用。良好的封装,便于修改内部代码,提高可维护性。良好的封装,可进行数据完整性检测,保证数据的有效性。使用访问控制符,实现封装à范围越来越大同一个类同一个包中子类所有类private*default**protected***public****封装的使用细节类的属性的处理:一般使用private.(除非本属性确定会让子类继承)提供相应的get/set方法来访问相关属性.这些方法通常是public,从而提供对属性的读取操作。(注意:boolean变量的get方法是用:is开头!)一些只用于本类的辅助性方法可以用private,希望其他类调用的方法用public。331 北京尚学堂科技JAVA基础课程多态(polymorphism)为什么需要多态?多态在现实里面也是经常出现、天天出现的。我们先不用管编程中的多态。下面我给大家打几个比方:我第一次去见丈母娘。还没见的时候,我女朋友已经把我的情况介绍给丈母娘了,说我“长得像港台明星”。见面以后丈母娘一看,哇,原来是像曾志伟。当场晕倒。这就是一种多态:没见我的时候,说的模糊一点留点想象空间,真见我后才亮出底细。我是老板,今天有点事要员工出去。打电话“小张,这边有点事过来一下”。让他过来以后,才跟他具体谈什么事。留出点空间,对不对?来了以后,才告诉他,去把地扫一下。我跟小张在外面吃饭,中途打电话叫小李“小李,快来,我们在某某饭馆,有好事”。小李一听,屁颠屁颠跑来。结果,发现是我和小张钱不够,让他请客。这些事情,都是多态。就是在做之前,不要把话说死,说的模糊一点想象空间大一点,真做的时候再具体化。在国家层面也有,叫“模糊战略”。如何实现多态?java中如何实现多态?使用多态的好处?引用变量的两种类型:编译时类型(模糊一点,一般是一个父类)由声明时的类型决定。运行时类型(运行时,具体是哪个子类就是哪个子类)由实际对应的对象类型决定。通过动态绑定调用该对象的方法。动态绑定会使我们的程序编写更加灵活,但是会减慢程序运行速度。这也是JAVA比C++/C慢的主要原因之一。多态:如果编译时类型和运行时类型不一致,就会造成多态。多态性是OOP中的一个重要特性,主要是用来实现动态联编的,换句话说,就是程序的最终状态只有在执行过程中才被决定而非在编译期间就决定了。这对于大型系统来说能提高系统的灵活性和扩展性。331 北京尚学堂科技JAVA基础课程多态可以让我们不用关心某个对象到底是什么具体类型,就可以使用该对象的某些方法,从而实现更加灵活的编程,提高系统的可扩展性。方法绑定(methodbinding)执行调用方法时,JVM根据相关信息,能够执行内存地址中代表该方法的代码。静态绑定在编译期完成,可以提高代码执行速度。静态绑定的方法包括:1.静态方法2.构造器3.private方法4.用关键字super调用的方法动态绑定通过对象调用的方法,采用动态绑定机制。这虽然让我们编程灵活,但是降低了代码的执行速度。这也是JAVA比C/C++速度慢的主要因素之一。多态的使用要点要点:多态是方法的多态,属性没有多态性。编写程序时,如果想调用运行时类型的方法,只能进行类型转换。不然通不过编译器的检查。但是如果两个没有关联的类进行强制转换,会报:ClassCastException。比如:本来是狗,我把它转成猫。就会报这个异常。多态的存在要有3个必要条件:要有继承,要有方法重写,父类引用指向子类对象331 北京尚学堂科技JAVA基础课程packageobject;publicclassTestPolym{publicstaticvoidmain(String[]args){Animalanimal=newDog();//向上可以自动转型System.out.println(animal.age);//属性调用时,仍然是基类的属性。属性没有多态!//animal.shout();animalCry(newDog());//传的具体是哪一个类就调用哪一个类的方法。大大提高了程序的可扩展性。//如果没有多态,我们这里需要写很多重载的方法。如果增加一种动物,就需要重载一种动物的喊叫方法。非常麻烦。//有了多态,只需要增加这个类继承Animal基类就可以了。animalCry(newCat());Dogdog=(Dog)animal;//编写程序时,如果想调用运行时类型的方法,只能进行类型转换。不然通不过编译器的检查。dog.gnawBone();System.out.println(doginstanceofAnimal);System.out.println(animalinstanceofCat);System.out.println(animalinstanceofDog);}staticvoidanimalCry(Animala){a.shout();}331 北京尚学堂科技JAVA基础课程}classAnimal{intage=10;publicvoidshout(){System.out.println("叫了一声!");}}classDogextendsAnimal{intage=28;publicvoidshout(){System.out.println("旺旺旺!");}publicvoidgnawBone(){System.out.println("我再啃骨头");}}classCatextendsAnimal{intage=18;publicvoidshout(){System.out.println("喵喵喵喵!");}}331 北京尚学堂科技JAVA基础课程对象的转型(casting)为什么需要强制转换类型?引用变量只能调用它编译类型的方法,不能调用它运行类型的方法。这时,我们就需要进行类型的强制转换!³一个父类的引用类型变量可以“指向”其子类的对象。³一个父类的引用不可以访问其子类对象新增加的成员(属性和方法)。³可以使用引用变量instanceof类名来判断该引用型变量所“指向”的对象是否属于该类或该类的子类。³子类的对象可以当作基类的对象来使用称作向上转型(upcasting),反之称为向下转型(downcasting)classAnimal{publicStringname;Animal(Stringname){this.name=name;}}classCatextendsAnimal{publicStringeyesColor;Cat(Stringn,Stringc){super(n);eyesColor=c;}}classDogextendsAnimal{331 北京尚学堂科技JAVA基础课程publicStringfurColor;Dog(Stringn,Stringc){super(n);furColor=c;}}classTest{publicstaticvoidmain(String[]args){Animala=newAnimal("name");Dogd=newDog("wangwang","black");//System.out.println(ainstanceofAnimal);//System.out.println(cinstanceofAnimal);//System.out.println(dinstanceofAnimal);//System.out.println(ainstanceofCat);//a=newDog("bigyellow","yellow");//向下转型System.out.println(a.name);//System.out.println(a.furColor);//一个基类的引用不可以访问其子类对象新增加的成员(属性和方法)//可以使用引用变量instanceof类名来判断该引用型变量所“指向”的对象是否属于该类或该类的子类。System.out.println(ainstanceofAnimal);System.out.println(ainstanceofDog);331 北京尚学堂科技JAVA基础课程a=newCat("mm","green");if(ainstanceofCat){Catd1=(Cat)a;System.out.println(d1.eyesColor);}}}final修饰变量:被他修饰的变量不可改变。一旦赋了初值,就不能被重新赋值。修饰成员变量:修饰局部变量://final修饰局部变量的初始化finalintgg=20;finalinthh;hh=50;final修饰的是引用变量时,只是引用值不能改变。对应的对象内部的属性仍然可变。finalDogdog=newDog();//dog=newDog();//报错!dog.age=77;//仍然可以修改dog指向对象的属性常量的命名:publicclassTest{staticfinalinta;//常量要进行初始化,如果采用系统默认值的话,就失去了存在的意义。//因此必须显式初始化,可以直接赋值或初始化块中或构造函数中。//但只能赋值一次!finalintb;finalintc;finalintd=19;static{a=3;}{c=50;}331 北京尚学堂科技JAVA基础课程一般不用驼峰写法,而是全部大写加下划线分割。比如:finalintDOG_AGE=18;publicTest(){//TODOAuto-generatedconstructorstubb=20;}publicstaticvoidmain(String[]args){//final修饰局部变量的初始化finalintgg=20;finalinthh;hh=50;//final修饰引用变量时,只是引用值不能改变。对应的对象内部的属性仍然可变。finalDogdog=newDog();//dog=newDog();//报错!dog.age=77;//仍然可以修改dog指向对象的属性}}修饰方法:该方法不可被子类重写。但是可以被重载!在上面Animal、Dog、Cat中,Animal中的shout方法中增加final。则Dog和Cat中shout方法不能存在了!331 北京尚学堂科技JAVA基础课程如果父类方法是privatefinal,那么对子类完全不可见;子类也就可以定义自己的同名的方法。这个不是重写了,而是子类自己新定义的方法。修饰类:修饰的类不能有子类,不能被继承。比如:Math、String。抽象类为什么需要抽象类?如何定义抽象类?是一种模版模式。抽象类为所有子类提供了一个通用模版,子类可以在这个模版基础上进行扩展。通过抽象类,可以避免子类设计的随意性。比如我们上面设计的:Animal、Dog、Cat类。Dog类能不能不重写shout方法呢?是可以的。没有严格规定必须重写shout方法。对不对?事实上,像shout这样的方法,每个动物的叫声都是不一样的,所以最好把它的实现交给特定的子类来做。有人说,我能不能在Animal类提供一个shout方法的空实现。但是,子类仍然是可重写、也可不重写该方法。因此,自由度还是比较大。就是说,父类的模版对子类没有严格的限制。packageobject;publicclassTest{publicstaticvoidmain(String[]args){Animalanimal=newAnimal();//抽象类不能new,但是可以作为引用类型。}}abstractclassAnimal{abstractvoidshout();}classDogextendsAnimal{331 北京尚学堂科技JAVA基础课程通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。代码如下:abstractclassAnimal{abstract1.abstract不能和final一起使用。2.包含abstract方法的类必须是抽象类。及用abstract修饰class3.abstract不能修饰属性。voidshout()抽象方法没有方法体!;}classDogextendsAnimal{voidshout(){//TODOAuto-generatedmethodstubSystem.out.println("旺旺旺!");}}@Overridevoidshout(){//TODOAuto-generatedmethodstubSystem.out.println("旺旺旺!");}voidaa(){System.out.println("aaaa");}}抽象类的使用要点有抽象方法的类只能定义能抽象类抽象类不能实例化,及不能用new来实例化抽象类。抽象类可以包含属性、方法、构造方法。但是构造方法不能用来new实例,只能用来被子类调用。抽象类只能用来继承。抽象方法必须被子类实现。抽象类和普通父类的区别,就在于包含抽象方法,抽象方法必须被子类实现,从而可以对子类的设计进行规范。抽象类的作用说白了就是:实现了规范所有的子类都遵守的规定,都必须有的实现,就要规范。现实世界中的规范很多。比如:个人电脑、主板和芯片的接口规范、USB接口规范、内存接口规范。和具体实现的分离但是还不彻底。抽象类中也可以定义普通方法、属性。。通过abstract方法定义规范,然后要求子类必须定义具体实现。引用变量仍然可以定义为抽象类,这样就可以规范地实现多态了。331 北京尚学堂科技JAVA基础课程接口普通类:具体实现抽象类:具体实现,规范(抽象方法)接口:规范!为什么需要接口?为什么需要接口?接口和抽象类的区别?接口就是比“抽象类”还“抽象”的“抽象类”,可以更加规范的对子类进行约束。全面地专业地实现了:规范和具体实现的分离。抽象类还提供某些具体实现,接口不提供任何实现,接口中所有方法都是抽象方法。接口是完全面向规范的,规定了一批类具有的公共方法规范。从接口的实现者角度看,接口定义了可以向外部提供的服务这里服务是由方法具体体现的。。从接口的调用者角度看,接口定义了实现者能提供那些服务。接口是两个模块之间通信的标准,通信的规范。如果能把你要设计的系统之间模块之间的接口定义好,就相当于完成了系统的设计大纲,剩下的就是添砖加瓦的具体实现了。大家在工作以后,做系统时往往就是使用“面向接口”的思想来设计系统。定义交通工具时,我定义一个抽象类vehicle,在定义子类Car,plane,train。没有问题。抽象类和子类是一种一般和特殊的关系。接口呢,他和子类是实现规则的关系。比如:我定义一个借口Runnable,Car实现它就能在地上跑,train实现也能在地上跑。飞机实现它也能在地上跑。就是说,如果他是交通工具,就一定能跑,一定要实现Runnable。我再定义接口:Fligntable,如果要在天上飞就一定要实现Flightable接口。如何定义接口?格式:[访问修饰符]interface接口名[extends父接口1,父接口2…]{常量定义331 北京尚学堂科技JAVA基础课程方法定义}访问修饰符:只能是public或默认。接口名:和类名采用相同命名机制extends:接口可以多继承常量:接口中的属性只能是常量,总是:publicstaticfinal修饰。不写也是。方法:接口中的方法只能是:publicabstract。省略的话,也是publicabstract.接口的本质探讨接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想。如果你是天使,则必须能飞。如果你是汽车,则必须能跑。如果你好人,则必须干掉坏人;如果你是坏人,则必须欺负好人。接口的本质是契约,就像我们人间的法律一样。制定好后大家都遵守。OO的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如c++、java、c#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象。接口使用要点子类通过implements来实现接口中的规范接口不能创建实例,但是可用于声明引用变量类型。一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的。接口中只能包含静态常量、抽象方法,不能有普通属性、构造方法、普通方法。publicclassTest{publicstaticvoidmain(String[]args){Volantvolant=newAngel();volant.fly();331 北京尚学堂科技JAVA基础课程System.out.println(Volant.FLY_HIGHT);}}interfaceVolant{intFLY_HIGHT=100;//总是:publicstaticfinalvoidfly();//总是:publicabstractvoidfly2();}interfaceHonest{voidhelpOther();}classAngelimplementsVolant,Honest{publicvoidfly(){System.out.println("我是天使,飞起来啦!");}publicvoidhelpOther(){System.out.println("扶老奶奶过马路!");}}classGoodManimplementsHonest{publicvoidhelpOther(){System.out.println("扶老奶奶过马路!");}}331 北京尚学堂科技JAVA基础课程classBirdManimplementsVolant{publicvoidfly(){System.out.println("我是鸟人,正在飞!");}}classBirdimplementsVolant{publicvoidfly(){System.out.println("正在飞!");}}classPlaneimplementsVolant{publicvoidfly(){System.out.println("正在飞!");}}classSatelliteimplementsVolant{publicvoidfly(){System.out.println("正在飞!");}}classMissileimplementsVolant{publicvoidfly(){331 北京尚学堂科技JAVA基础课程System.out.println("正在飞!");}}接口的多继承接口完全支持多继承。和类的继承类似,子接口扩展某个父接口,将会获得父接口中所定义的一切。interfaceA{voidtesta();}interfaceB{voidtestb();}interfaceCextendsA,B{voidtestc();}publicclassTestimplementsC{publicvoidtestc(){}publicvoidtesta(){}331 北京尚学堂科技JAVA基础课程publicvoidtestb(){}}面向接口编程面向接口编程是面向对象编程的一部分。为什么需要面向接口编程?软件设计中最难处理的就是需求的复杂变化,需求的变化更多的体现在具体实现上。我们的编程如果围绕具体实现来展开就会陷入”复杂变化”的汪洋大海中,软件也就不能最终实现。我们必须围绕某种稳定的东西开展,才能以静制动,实现规范的高质量的项目。接口就是编程中最稳定的东东!面向接口编程可以让我把握住真正核心的东西,使实现复杂的多变的需求成为可能。通过面向接口编程,而不是面向实现类编程,可以大大降低程序模块间的耦合性,提高整个系统的可扩展性和和可维护性。面向接口编程的概念比接口本身的概念要大得多。设计难了,在你没有写实现时就要想好接口,接口一变就乱套了,设计要比实现难!OOP更多应用组合使用组合,可以获得更多的灵活性,你甚至可以在运行的时候才决定把哪几个类组合在一起。  使用继承,他是一种高度的耦合,派生类和基类被紧紧的绑在一起,灵活性大大降低,而且,滥用继承,也会使继承树变得又大又复杂,很难理解和维护如果是”is-a”关系,用继承。如果是”has-a”关系,用组合。classComputer{Cpucpu;331 北京尚学堂科技JAVA基础课程Mainboardmd;Mousemouse;}classCpu{}classMainboard{}classMouse{}内部类(innerclasses)一般情况,我们把类定义成独立的单元。有些情况下,我们把一个类放在另一个类的内部定义,称为内部类。内部类的作用:1.内部类提供了更好的封装。只能让外部类直接访问,不允许同一个包中的其他类直接访问。2.内部类可以直接访问外部类的私有属性,内部类被当成其外部类的成员。但外部类不能访问内部类的内部属性。内部类的使用场合:由于内部类提供了更好的封装特性,并且可以很方便的访问外部类的属性。所以,通常内部类在只为所在外部类提供服务的情况下优先使用。331 北京尚学堂科技JAVA基础课程内部类的分类:1.成员内部类(可以使用private、proteted、public任意进行修饰。类文件:外部类$内部类.class)a)非静态内部类(外部类里使用非静态内部类和平时使用其他类没什么不同)i.非静态内部类必须寄存在一个外部类对象里。因此,如果有一个非静态内部类对象那么一定存在对应的外部类对象。非静态内部类对象单独属于外部类的某个对象。ii.非静态内部类可以使用外部类的成员,但是外部类不能直接访问非静态内部类成员。iii.非静态内部类不能有静态方法、静态属性、静态初始化块。iv.静态成员不能访问非静态成员:外部类的静态方法、静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义变量、创建实例。v.成员变量访问要点:1.内部类里方法的局部变量:变量名2.内部类属性:this.变量名3.外部类属性:外部类名.this.变量名vi.内部类的访问:1.外部类中定义内部类:newInnerClass()2.外部类以外的地方使用非静态内部类:Outer.innervarname=OuterObject.newInner()Face.Nosenose=newFace().newNose();Facef2=newFace();Face.Nosenose2=f2.newNose();b)静态内部类i.定义方式:staticclassClassName{331 北京尚学堂科技JAVA基础课程//类体}i.使用要点:1.当一个静态内部类对象存在,并不一定存在对应的外部类对象。因此,静态内部类的实例方法不能直接访问外部类的实例方法。2.静态内部类看做外部类的一个静态成员。因此,外部类的方法中可以通过:静态内部类.名字访问静态内部类的静态成员。通过new静态内部类()访问静态内部类的实例。3.在外部类的外面创建静态内部类:Face.TestStaticInneraInner=newFace.TestStaticInner();2.匿名内部类适合那种只需要使用一次的类。比如:键盘监听操作等等。语法:new父类构造器(实参类表)实现接口(){//匿名内部类类体!}this.addWindowListener(newWindowAdapter(){@OverridepublicvoidwindowClosing(WindowEvente){System.exit(0);}});this.addKeyListener(newKeyAdapter(){@OverridepublicvoidkeyPressed(KeyEvente){//TODOAuto-generatedmethodstub331 北京尚学堂科技JAVA基础课程myTank.keyPressed(e);}@OverridepublicvoidkeyReleased(KeyEvente){//TODOAuto-generatedmethodstubmyTank.keyReleased(e);}});局部内部类定义在方法内部。作用域只限于本方法。用的非常少。字符串(java.lang.String类)的使用nJava字符串就是Unicode字符序列,例如串“Java”就是4个Unicode字符J,a,v,a组成的。nJava没有内置的字符串类型,而是在标准Java类库中提供了一个预定义的类String,每个用双引号括起来的字符串都是String类的一个实例。Stringe=“”;//anemptystringStringgreeting=“HelloWorld”;nJava允许使用符号"+"把两个字符串连接起来Strings1=“Hello”;Strings2=“World!”;Strings=s1+s2;//HelloWorld!n符号“+”把两个字符串按给定的顺序连接在一起,并且是完全按照给定的形式。n当“+”运算符两侧的操作数中只要有一个是字符串(String)类型,系统会自动将另一个操作数转换为字符串然后再进行连接331 北京尚学堂科技JAVA基础课程intage=18;Strings="ageis"+age;//s赋值为ageis18这种特性通常被用在输出语句中:System.out.println(“ageis”+age);开始学习阅读API文档:字符串类常用的方法:ncharcharAt(intindex)返回字符串中第index个字符。nbooleanequals(Stringother)如果字符串与other相等,返回truenbooleanequalsIgnoreCase(Stringother)如果字符串与other相等(忽略大小写),则返回truenintindexOf(Stringstr)lastIndexOf()nintindexOf(Stringstr,intfromIndex)返回与str匹配的第一个字串的开始位置,该位置从0或fromIndex开始计算,如果原始串中不存在str,返回-1.nintlength()返回字符串的长度。nStringreplace(charoldChar,charnewChar)331 北京尚学堂科技JAVA基础课程返回一个新串,它是通过用newChar替换此字符串中出现的所有oldChar而生成的publicclassStringTest1{publicstaticvoidmain(String[]args){Strings1="corejava";Strings2="CoreJava";System.out.println(s1.charAt(4));System.out.println(s2.length());System.out.println(s1.equals(s2));System.out.println(s1.equalsIgnoreCase(s2));System.out.println(s1.indexOf("java"));System.out.println(s1.indexOf("apple"));Strings=s1.replace("","&");System.out.println("resultis:"+s);}}nbooleanstartsWith(Stringprefix)如果字符串以prefix开始,则返回truenbooleanendsWith(Stringprefix)如果字符串以prefix结尾,则返回truenStringsubstring(intbeginIndex)nStringsubstring(intbeginIndex,intendIndex)n返回一个新字符串,该串包含从原始字符串beginIndex到串尾或endIndex-1的所以字符nStringtoLowerCase()返回一个新字符串,该串将原始字符串中的所有大写字母改成小写字母nStringtoUpperCase()返回一个新字符串,该串将原始字符串中的所有小写字母改成大写字母nStringtrim()331 北京尚学堂科技JAVA基础课程返回一个新字符串,该串删除了原始字符串头部和尾部的空格publicclassStringTest2{publicstaticvoidmain(String[]args){Strings="";Strings1="Howareyou?";System.out.println(s1.startsWith("How"));System.out.println(s1.endsWith("you"));s=s1.substring(4);System.out.println(s);s=s1.substring(4,7);System.out.println(s);s=s1.toLowerCase();System.out.println(s);s=s1.toUpperCase();System.out.println(s);Strings2="Howoldareyou!!";s=s2.trim();System.out.println(s);System.out.println(s2);//???}}字符串相等的判断nequals方法用来检测两个字符串内容是否相等。如果字符串s和t内容相等,则s.equals(t)返回true,否则返回false.ns和t既可以是字符串变量,也可以是字符串常数,例如:“Hello”.equals(t);n要测试两个字符串除了大小写区别外是否是相等的,需要使用equalsIgnoreCase方法,例如:“Hello”.equalsIgnoreCase(“hellO”);//truen判断字符串是否相等不要使用“==”Stringg1="HelloWorld!";Stringg2="HelloWorld!";331 北京尚学堂科技JAVA基础课程booleanb1=g1.equals(g2);System.out.println("tg1.equals(g2)是否相等:"+(b1?"相等":"不相等"));booleanb2=(g1==g2);System.out.println("tg1==g2是否相等:"+(b2?"相等":"不相等"));System.out.println("=========================================");Strings1=newString("HelloWorld!");Strings2=newString("HelloWorld!");booleanb3=s1.equals(s2);System.out.println("ts1.equals(s2)是否相等:"+(b3?"相等":"不相等"));booleanb4=(s1==s2);System.out.println("ts1==s2是否相等:"+(b4?"相等":"不相等"));}}/***g1.equals(g2)是否相等:相等*g1==g2是否相等:相等*======================================*s1.equals(s2)是否相等:相等*s1==s2是否相等:不相等为什么?**问:为什么会产生以上不同的结果,你能说明其原因吗?*(或者画内存变化图来说明)*/331 北京尚学堂科技JAVA基础课程思考作业1.举例说明类和对象的关系2.使用企业管理模式的变化说明类和对象的进化史。3.提示:企业:一个人、小作坊、小企业、现代企业等。4.成员变量和类变量的关系?实例方法和静态方法的关系?5.构造器哪些地方不同于普通的方法?6.为什么需要方法的重载?重载的要点?7.面向过程和面向对象的关系?8.解释下,静态初始化块的作用?静态初始化块的执行时机?9.package的作用?是如何实现类的管理的?10.为什么需要import?11.this是做什么的?12.Super指的是什么?13.变量和方法,使用static修饰后,变成了什么?静态变量是否被该类所有对象共享?14.“is-a”和”has-a”关系哪种更加适用继承?15.实现封装的几个关键字分别是哪些?作用范围?16.Object类中的toString方法的作用?17.为什么需要多态?举例说明一个现实中多态的例子?18.多态实现的基本条件是什么?写出一个多态的例子?19.Final修饰变量、方法、类各自代表什么含义?20.继承链中,构造方法的调用顺序?21.继承中,JAVA为什么不需要多继承了?22.有抽象方法的类一定是抽象类吗?23.用自己的话,描述为什么需要接口?24.使用接口描述:电子产品系列、化妆品系列25.接口中,能否定义变量?并解释为什么?331 北京尚学堂科技JAVA基础课程上机作业1.学会查看API文档2.将课堂上,内存分析例子重新画一遍3.针对每个知识点,做测试练习4.完成游戏开发:a)太阳系模拟程序改版b)洪七公打狗游戏开发331 北京尚学堂科技JAVA基础课程第四章异常机制导引问题实际工作中,遇到的情况不可能是非常完美的。比如:你写的某个模块,用户输入不一定符合你的要求、你的程序要打开某个文件,这个文件可能不存在或者文件格式不对,你要读取数据库的数据,数据可能是空的等。我们的程序再跑着,内存或硬盘可能满了。等等。软件程序在运行过程中,非常可能遇到刚刚提到的这些异常问题,我们叫异常,英文是:Exception,意思是例外。这些,例外情况,或者叫异常,怎么让我们写的程序做出合理的处理。而不至于程序崩溃。常见的错误:1.用户输入错误2.设备错误硬件问题,比如打印机关掉、服务器问题3.物理限制磁盘满了。4.代码限制数组下标越界等设计良好的程序应该在异常发生时提供处理这些错误的方法,使得程序不会因为异常的发生而终断或产生不可预见的结果。如果没有异常处理机制,那么:331 北京尚学堂科技JAVA基础课程//将d:/a.txt复制到e:/a.txtif("d:/a.txt"这个文件存在){if(e盘的空间大于a.txt文件长度){if(文件复制一半IO流断掉){停止copy,输出:IO流出问题!}else{copyFile("d:/a.txt","e:/a.txt");}}else{输出:e盘空间不够存放a.txt!}}else{输出:a.txt不存在!}两个坏处:1.逻辑代码和错误处理代码放一起!2.程序员本身需要考虑的例外情况较复杂,对程序员本身要求较高!异常机制就是当程序出现错误,程序如何安全退出的机制。异常(Exception)的概念JAVA如何处理异常?第一个异常示例和解析:publicstaticvoidmain(String[]args){inti=1/0;331 北京尚学堂科技JAVA基础课程gggggg}Exceptioninthread"main"java.lang.ArithmeticException:/byzeroatchuji.BubbleSort.main(BubbleSort.java:11)JAVA是采用面向对象的方式来处理异常的。处理过程:1.抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给JRE。2.捕获异常:JRE得到该异常后,寻找相应的代码来处理该异常。JRE在方法的调用栈中查找,从生成异常的方法开始回溯,直到找到相应的异常处理代码为止。异常分类JDK中定义了很多异常类,这些类对应了各种各样可能出现的异常事件,所有异常对象都是派生于Throwable类的一个实例。如果内置的异常类不能够满足需要,还可以创建自己的异常类。ErrorError类层次描述了Java运行时系统内部错误和资源耗尽错误。这类错误是我们无法控制的,同时也是非常罕见的错误。所以在编程中,不去处理这类错误。331 北京尚学堂科技JAVA基础课程Error表明系统JVM已经处于不可恢复的崩溃状态中。我们不需要管他。打开JDK的:java.lang.error,查看他的所有子类。Error和Exception的区别:我开着车走在路上,一头猪冲在路中间,我刹车。这叫一个异常。我开着车在路上,发动机坏了,我停车,这叫错误。系统处于不可恢复的崩溃状态。发动机什么时候坏?我们普通司机能管吗?不能。发动机什么时候坏是汽车厂发动机制造商的事。Exception所有异常类的父类,其子类对应了各种各样可能出现的异常事件。nRuntimeException(uncheckedException)出现RuntimeException就一定是你的问题你开车路上跑,中间忽然出现一个猪,你不能说是汽车厂的事吧?撞猪了,那是你的事,你得赔。因此,出现异常就是你的问题。,可以不捕获,因为小心点这些异常是可以避免的。派生于RuntimeException的异常。是一类特殊的异常,如被0除、数组下标超范围等,其产生比较频繁,处理麻烦,如果显式的声明或捕获将会对程序可读性和运行效率影响很大。因此由系统自动检测并将它们交给缺省的异常处理程序(用户可不必对其处理)。这类异常通常是由编程错误导致的,因为只有小心点,这些异常都是可以避免的,所以在编写程序时,并不要求必须使用异常处理机制来处理这类异常,所有这类异常都继承自java.lang.RuntimeException。注意:RuntimeException这个名字很容易让人产生错误影响。事实上,我们这里讨论的所有Error、Exception都是运行时发生的。常见的有:1.ArithmeticException如试图除以0if(b!=0){331 北京尚学堂科技JAVA基础课程inti=1/b;}else{System.out.println("不能用0做除数!!");}1.NullPointerException当程序访问一个空对象的成员变量或方法,访问一个空数组的成员时发生。怎么处理?//TestExceptionte=null;TestExceptionte=newTestException();if(te!=null){te.test1(2);}2.ClassCastExceptionvoidtest2(Objectobj){if(objinstanceofMan){Manman=(Man)obj;}}3.ArrayIndexOutOfBoundsException访问的元素下表超过数组长度int[]a={1,2,3};intidx=3;if(idx<=a.length-1){System.out.println(a[idx]);331 北京尚学堂科技JAVA基础课程}1.NumberFormatException数字格式异常!Stringstr="1234abcf";Integeri=newInteger(str);//Integeri2=Integer.parseInt(str);nChecked为什么叫已检查异常?Checked,运行前已经检查过。就是编译器会检查是否对这些异常做了处理。unchecked异常指的是编译器不会做检查。error是unchecked的,因为我们无法控制他;RuntimeException太频繁了,并且编译器也无法检查。Exception:所有不是RuntimeException的异常,统称为CheckedException,又被称为“已检查异常”。这类异常的产生不是程序本身的问题,通常由外界因素造成的。为了预防这些异常产生时,造成程序的中断或得到不正确的结果,Java要求编写可能产生这类异常的程序代码时,一定要去做异常的处理。1.要打开的文件不存在编译器将检查是否为所有已检查异常提供异常处理。这一类异常,我们必须捕获进行处理。nJava语言将派生于RuntimeException类或Error类的所有异常称为“未检查异常”。异常的处理办法之一,捕获异常try{抛出异常语句1;语句2;}catch(Exception1e){}catch(Exception2e){}finally{331 北京尚学堂科技JAVA基础课程}上面过程详细解析:try块try语句指定了一段代码,该段代码就是一次捕获并处理的范围。在执行过程中,当任意一条语句产生异常时,就会跳过该段中后面的代码。代码中可能会产生并抛出一种或几种类型的异常对象,它后面的catch语句要分别对这些异常做相应的处理n一个try语句必须带有至少一个catch语句块或一个finally语句块。。注:当异常处理的代码执行结束以后,是不会回到try语句去执行尚未执行的代码。catcha)每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。b)常用方法:toString()方法,显示异常的类名和产生异常的原因getMessage()方法,只显示产生异常的原因,但不显示类名。printStackTrace()方法,用来跟踪异常事件发生时堆栈的内容。这些方法均继承自Throwable类c)Catch捕获异常时的捕获顺序:i.如果异常类之间有继承关系,在顺序安排上需注意。越是顶层的类,越放在下面。事实上,放反了,编译通不过去。Eclipse当时就会报错!再不然就直接把多余的catch省略掉。finally有些语句,不管是否发生了异常,都必须要执行,那么就可以把这样的语句放到331 北京尚学堂科技JAVA基础课程finally语句块中。通常在finally中关闭程序块已打开的资源,比如:文件流、释放数据库连接等。典型代码(先不要敲!!):packagecom.bjsxt.four;importjava.io.FileNotFoundException;importjava.io.FileReader;importjava.io.IOException;publicclassTestReadFile{publicstaticvoidmain(String[]args){FileReaderreader=null;try{reader=newFileReader("d:/a.txt");charc=(char)reader.read();charc2=(char)reader.read();System.out.println(""+c+c2);}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}finally{try{if(reader!=null){reader.close();}331 北京尚学堂科技JAVA基础课程}catch(Exceptione){e.printStackTrace();}}}}try,catch,finally,return执行顺序packagecom.bjsxt.four;importjava.io.FileNotFoundException;importjava.io.FileReader;importjava.io.IOException;publicclassTestReadFile{publicstaticvoidmain(String[]args){Stringstr=newTestReadFile().openFile();System.out.println(str);}StringopenFile(){try{System.out.println("aaa");FileReaderfis=newFileReader("d:/a.txt");//checked!!!inta=fis.read();System.out.println("bbb");return"step1";331 北京尚学堂科技JAVA基础课程}catch(FileNotFoundExceptione){System.out.println("catching!!!!");e.printStackTrace();return"step2";//先确定返回的值,并不会直接结束运行!}catch(IOExceptione){e.printStackTrace();return"step3";}finally{System.out.println("finally!!!!");//return"fff";//尽量不要再finally中使用return!}}}执行顺序:1.执行try,catch,给返回值赋值2.执行finally3.return异常的处理办法之二,声明异常:throws子句当CheckedException产生时,不一定立刻处理它,可以再把异常Throws出去。在方法中使用try-chatch-finally由这个方法处理异常。在一些情况下,当前方法并不需要处理发生的异常,而是向上传递给调用它的方法处理。如果一个方法中可能产生某种异常,但是并不能确定如何处理这种异常,则应根据异常规范在方法的首部声明该方法可能抛出的异常。n如果一个方法抛出多个已检查异常,就必须在方法的首部列出所有的异常,之间以逗号隔开。331 北京尚学堂科技JAVA基础课程典型代码(先不敲!):publicclassFileTest2{publicstaticvoidmain(String[]args){try{readFile("joke.txt");}catch(FileNotFoundExceptione){System.out.println("所需文件不存在!");}catch(IOExceptione){System.out.println("文件读写错误!");}}publicstaticvoidreadFile(StringfileName)throwsFileNotFoundException,IOException{FileReaderin=newFileReader(fileName);inttem=0;try{tem=in.read();while(tem!=-1){System.out.print((char)tem);tem=in.read();}}finally{in.close();}}方法重写中声明异常原则n子类声明的异常范围不能超过父类声明的范围。包含如下意思:1.父类没有声明异常,子类也不能;331 北京尚学堂科技JAVA基础课程1.不可抛出原有方法抛出异常类的父类或上层类2.抛出的异常类型的数目不可以比原有的方法抛出的还多(不是指个数)代码示例:importjava.io.*;importjava.text.ParseException;classA{publicvoidmethod()throwsIOException{}}classBextendsA{publicvoidmethod()throwsFileNotFoundException{}}classCextendsA{publicvoidmethod(){}}classDextendsA{publicvoidmethod()throwsException{}}classEextendsA{publicvoidmethod()throwsIOException,FileNotFoundException{}}classFextendsA{publicvoidmethod()throwsIOException,ArithmeticException{}}classGextendsA{publicvoidmethod()throwsIOException,ParseException{}}异常的处理办法之三,手动抛出异常,throw子句nJava异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可根据需要手工创建并抛出。n在捕获一个异常前,必须有一段代码先生成异常对象并把它抛出。这个过程我们可以手工做,也可以由JRE来实现,但是他们调用的都是throw子句。n对于一个已经存在的异常类,抛出该类异常对象过程如下:331 北京尚学堂科技JAVA基础课程u找到一个合适的异常类。u创建一个该类的对象。u将对象抛出Filef=newFile("c:/tt.txt");if(!f.exists()){try{thrownewFileNotFoundException("Filecan"tbefound!");}catch(FileNotFoundExceptione){e.printStackTrace();}}自定义异常n在程序中,可能会遇到任何标准异常类都没有充分的描述清楚的问题,这种情况下可以创建自己的异常类n从Exception类或者它的子类派生一个子类即可n习惯上,定义的类应该包含2个构造器:一个是默认的构造器,另一个是带有详细信息的构造器classIllegalAgeExceptionextendsException{publicIllegalAgeException(){}publicIllegalAgeException(Stringmsg){super(msg);}}331 北京尚学堂科技JAVA基础课程classPerson{privateStringname;privateintage;publicvoidsetName(Stringname){this.name=name;}publicvoidsetAge(intage){if(age<0)thrownewIllegalAgeException("人的年龄不应该为负数");this.age=age;}publicStringtoString(){return"nameis"+name+"andageis"+age;}}publicclassMyExceptionTest{publicstaticvoidmain(String[]args){Personp=newPerson();try{p.setName("Lincoln");p.setAge(-1);}catch(IllegalAgeExceptione){e.printStackTrace();System.exit(-1);}331 北京尚学堂科技JAVA基础课程System.out.println(p);}}使用异常机制建议1.要避免使用异常处理代替错误处理,这样会降低程序的清晰性,并且效率低下。2.处理异常不可以代替简单测试---只在异常情况下使用异常机制3.不要进行小粒度的异常处理---应该将整个任务包装在一个Try语句块中4.异常往往在高层处理(先了解!后面做项目会说!)总结³一个图³五个关键字(try,catch,finally,throws,throw)³先逮小的,再逮大的³异常和重写的关系³自定义异常思考作业1.Throwable类定义了一些方法,其中printStackTrace()反悔什么信息,getMessage()和toString()又返回什么信息?2.说明try,catch,finally,return的执行顺序3.说出你现在接触的几个异常?尽量多写。上机作业1.完成课堂上老师的代码!331 北京尚学堂科技JAVA基础课程1.测试每一个知识点,让自己有一个感性的认识!331 北京尚学堂科技JAVA基础课程第五章数组数组概述和特点n数组的定义:数组是相同类型数据的有序集合.数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们.n数组的四个基本特点:1.其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。2.其元素必须是相同类型,不允许出现混合类型。3.数组中的元素可以是任何数据类型数组是引用类型。数组里面也可以放数组,包括基本类型和引用类型。4.数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。创建数组和初始化n声明(一维数组的声明方式有两种)type[]arr_name;(推荐使用这中方式)typearr_name[];注:1.声明的时候并没有实例化任何对象,只有在实例化数组对象时,JVM才分配空间,这时才与长度有关。因此,声明数组时不能指定其长度(数组中元素的个数),例如:inta[5];//非法2.声明一个数组的时候并没有数组被真正的创建。331 北京尚学堂科技JAVA基础课程1.构造一个数组,必须指定长度。n构建数组:创建基本类型一维数组示例:publicclassTest{publicstaticvoidmain(Stringargs[]){int[]s=null;//1s=newint[10];//2for(inti=0;i<10;i++){s[i]=2*i+1;System.out.println(s[i]);}//3}}创建引用类型一维数组示例:classMan{privateintage;privateintid;publicMan(intid,intage){super();this.age=age;this.id=id;}}331 北京尚学堂科技JAVA基础课程publicclassAppMain{publicstaticvoidmain(String[]args){Man[]mans;mans=newMan[10];//1Manm1=newMan(1,11);Manm2=newMan(2,22);//2mans[0]=m1;mans[1]=m2;//3}}n初始化u静态初始化除了用new关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值。int[]a={1,2,3};Man[]mans={newMan(1,1),newMan(2,2)};u动态初始化数组定义与为数组元素分配空间并赋值的操作分开进行。int[]a=newint[2];a[0]=1;a[1]=2;331 北京尚学堂科技JAVA基础课程u数组的默认初始化:数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。inta[]=newint[2];//0,0boolean[]b=newboolean[2];//false,falseString[]s=newString[2];//null,nulln数组的界限1.下标的合法区间:[0,length是数组的length属性-1]1定义4特点3初始化方式!数组常见操作数组的拷贝System类里也包含了一个staticvoidarraycopy(objectsrc,intsrcpos,objectdest,intdestpos,intlength)方法,该方法可以将src数组里的元素值赋给dest数组的元素,其中srcpos指定从src数组的第几个元素开始赋值,length参数指定将src数组的多少个元素赋给dest数组的元素。String[]s={"Mircosoft","IBM","Sun","Oracle","Apple"};String[]sBak=newString[6];System.arraycopy(s,0,sBak,0,s.length);njava.util.Arrays1.打印数组int[]a={1,2};System.out.println(a);//[I@35ce36System.out.println(Arrays.toString(a));//[1,2]331 北京尚学堂科技JAVA基础课程数组排序int[]a={1,2,323,23,543,12,59};System.out.println(Arrays.toString(a));Arrays.sort(a);System.out.println(Arrays.toString(a));结果:[1,2,323,23,543,12,59][1,2,12,23,59,323,543]如果数组元素是引用类型,那么需要怎么做呢?(今天先不讲!后面讲容器时再讲!)publicclassTest{publicstaticvoidmain(String[]args){Man[]msMans={newMan(3,"a"),newMan(60,"b"),newMan(2,"c")};Arrays.sort(msMans);System.out.println(Arrays.toString(msMans));}}classManimplementsComparable{intage;intid;Stringname;publicMan(intage,Stringname){super();331 北京尚学堂科技JAVA基础课程this.age=age;this.name=name;}publicStringtoString(){returnthis.name;}publicintcompareTo(Objecto){Manman=(Man)o;if(this.ageman.age){return1;}return0;}比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。}1.二分法查找int[]a={1,2,323,23,543,12,59};Arrays.sort(a);//使用二分法查找,必须先对数组进行排序System.out.println("该元素的索引:"+Arrays.binarySearch(a,12));331 北京尚学堂科技JAVA基础课程1.复制一般用System.arraycopy2.填充Arrays.fill(a,2,4,100);//将2到4索引的元素替换为1003.asList(暂时不讲,讲完容器后再说。事实上用的也不多)int[]a={1,2,323,23,543,12,59};Listlist=newArrayList();list=Arrays.asList(a);//将数组转成成list对象中的一个元素System.out.println(list.get(0)[1]);多维数组多维数组可以看成以数组为元素的数组。例如:静态初始化:int[][]a={{1,2,3},{3,4},{3,5,6,7}};331 北京尚学堂科技JAVA基础课程System.out.println(a[2][3]);动态初始化:int[][]a=newint[3][]这个维度不用指定吗;//a[0]={1,2,5};//错误,没有声明类型就初始化a[0]=newint[]{1,2};a[1]=newint[]{2,2};a[2]=newint[]{2,2,3,4};System.out.println(a[2][3]);获取数组长度:a.length获取的二维数组第一维数组的长度,a[0].length才是获取第二维第一个数组长度。附录(面试前复习一下!!)冒泡排序publicclassTest{publicstaticvoidmain(String[]args){int[]values={3,1,6,2,9,0,7,4,5,8};sort(values);System.out.println(Arrays.toString(values));}publicstaticvoidsort(int[]values){inttemp;for(inti=0;ivalues[j+1]){temp=values[j];values[j]=values[j+1];values[j+1]=temp;}}}}}二分法查找importjava.util.Arrays;publicclassTestBinarySearch{publicstaticvoidmain(String[]args){System.out.println(args[1]);int[]arr={234,245,77,3,543,67,78,95,378,678,205,753,457,2903,340};intsearchWord=6780;//所要查找的数intsearchCount=0;//循环的次数System.out.printf("普通循环查找%d的次数是%d",searchWord,genetalLoop(arr,searchWord));System.out.printf("二分法查找%d的次数是%d",searchWord,binarySearch(arr,searchWord));}staticintgenetalLoop(int[]arr,intsearchWord){331 北京尚学堂科技JAVA基础课程//普通的循环法,最少需要比较一次,比如查找1,最多需要比较15次,比如8721intsearchCount=0;for(inti=0;isearchWord){System.out.println("bb");331 北京尚学堂科技JAVA基础课程iEnd=iIndex;}else{break;}}returnsearchCount;}}命令行参数的问题publicclassTest{publicstaticvoidmain(String[]args){for(inti=0;i角度toRadians(doubleangdeg)角度->弧度331 北京尚学堂科技JAVA基础课程File类放入:IO一章中讲授。File类的基本用法Øjava.io.File类:文件和目录路径名的抽象表示形式。ØFile类的常见构造方法:§publicFile(Stringpathname)以pathname为路径创建File对象,如果pathname是相对路径,则默认的当前路径在系统属性user.dir中存储。ØFile的静态属性Stringseparator存储了当前系统的路径分隔符。Ø通过File对象可以访问文件的属性。publicbooleancanRead()publicbooleancanWrite()publicbooleanexists()publicbooleanisDirectory()publicbooleanisFile()publicbooleanisHidden()publiclonglastModified()publiclonglength()publicStringgetName()publicStringgetPath()Ø通过File对象创建空文件或目录(在该对象所指的文件或目录不存在的情况下)。publicbooleancreateNewFile()throwsIOExceptionpublicbooleandelete()publicbooleanmkdir(),mkdirs()注意两个的区别!!树状结构展现文件结构编写一个程序,在命令行中以树状结构展现特定的文件夹及其子文件(夹)packagecom.bjsxt.io;331 北京尚学堂科技JAVA基础课程importjava.io.File;publicclassFileTree{publicstaticvoidmain(String[]args){Filef=newFile("d:/1005班");printFile(f,0);}staticvoidprintFile(Filefile,intlevel){for(inti=0;imaps=newHashMap();SetkeySet=maps.keySet();for(Integerid:keySet){331 北京尚学堂科技JAVA基础课程System.out.println(maps.get(id).name);}//使用entrySet遍历Set>ss=map.entrySet();for(Iteratoriterator=ss.iterator();iterator.hasNext();){Entrye=(Entry)iterator.next();System.out.println(e.getKey()+"--"+e.getValue());}Collections工具类类java.util.Collections提供了对Set、List、Map操作的工具方法。voidsort(List)//对List容器内的元素排序,//排序的规则是按照升序进行排序。voidshuffle(List)//对List容器内的元素进行随机排列voidreverse(List)//对List容器内的元素进行逆续排列voidfill(List,Object)//用一个特定的对象重写整个List容器intbinarySearch(List,Object)//对于顺序的List容器,采用折半查找的//方法查找特定对象ListaList=newArrayList();for(inti=0;i<5;i++)aList.add("a"+i);System.out.println(aList);Collections.shuffle(aList);//随机排列System.out.println(aList);Collections.reverse(aList);//逆续331 北京尚学堂科技JAVA基础课程System.out.println(aList);Collections.sort(aList);//排序System.out.println(aList);System.out.println(Collections.binarySearch(aList,"a2"));Collections.fill(aList,"hello");System.out.println(aList);Comparable接口Ø问题:上面的算法根据什么确定集合中对象的“大小”顺序?Ø所有可以“排序”的类都实现了java.lang.Comparable接口,Comparable接口中只有一个方法publicintcompareTo(Objectobj);该方法:§返回0表示this==obj§返回正数表示this>obj§返回负数表示thislist=newArrayList();Studentstu1=newStudent(1,"张三",100);331 北京尚学堂科技JAVA基础课程Studentstu2=newStudent(2,"张四",80);Studentstu3=newStudent(3,"张五",90);list.add(stu1);list.add(stu2);list.add(stu3);System.out.println(list);Collections.sort(list);System.out.println(list);}}classStudentimplementsComparable{intid;Stringname;intscore;publicStudent(intid,Stringname,intscore){super();this.id=id;this.name=name;this.score=score;}publicStringtoString(){returnname+score;}331 北京尚学堂科技JAVA基础课程@OverridepublicintcompareTo(Studento){if(this.score>o.score){return1;}elseif(this.scorelist=newArrayList();Setmans=newHashSet();Mapmaps=newHashMap();Iteratoriterator=mans.iterator();思考作业1.Collection和Collections的区别。Collections是个java.util下的类,它包含有各种有关集合操作的静态方法。Collection是个java.util下的接口,它是各种集合结构的父接口。2.List,Set,Map是否继承自Collection接口?List,Set是 Map不是3.ArrayList和Vector的区别。一.同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的。331 北京尚学堂科技JAVA基础课程二.数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半。1.HashMap和Hashtable的区别同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的上机作业1.完成老师课堂作业2.如何遍历map3.升级上次的贪吃蛇作业!4.完成坦克大战小游戏!第八章IO技术为什么需要学习IO技术对于任何程序设计语言而言,输入输出(I/O)系统都是比较复杂的而且是比较核心的。程序运行需要数据,数据的获取往往需要跟外部系统进行通信,外部系统可能是文件、数据库、其他程序、网络、IO设备等等。我们可以发现,外部系统比较复杂多变,那么我们有必要通过某种手段进行抽象、屏蔽外部的差异。我们希望通过某种技术实现对所有外部系统的输入输出操作,java.io包为我们提供了相关的API,这就是我们这章所要学习的技术。331 北京尚学堂科技JAVA基础课程基本概念数据源datasource.提供原始数据的原始媒介。常见的:数据库、文件、其他程序、内存、网络连接、IO设备。流的概念Stream:名词,水流,趋势。动词:流出,流动数据源就像水箱,流就像水管中流着的水流,程序就是我们最终的用户。流是一个抽象、动态的概念,是一连串连续动态的数据集合。第一个简单的IO流程序及深入(将文件中的数据读入)当程序需要读取数据源的数据时,就会通过IO流对象开启一个通向数据源的流,通过这个IO流对象相关方法可以顺序读取这个特点,我们在介绍方法的用法时,尤其注意。流中的数据。同理,通过流向目的地写入数据通过流来处理。基本代码如下:这个代码是通过流对象从一个文件中读取数据:try{331 北京尚学堂科技JAVA基础课程FileInputStreamfis=newFileInputStream("d:/a.txt");//内容是:abcints1=fis.read();//97ints2=fis.read();//98ints3=fis.read();//99ints4=fis.read();//-1ints5=fis.read();//-1System.out.println(s1);fis.close();}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}上面的代码可以升级为如下更加标准的代码:FileInputStreamfis=null;try{fis=newFileInputStream("d:/a.txt");//内容是:abcStringBuildersb=newStringBuilder();inttemp=0;while((temp=fis.read())!=-1){sb.append((char)temp);}System.out.println(sb);}catch(FileNotFoundExceptione){331 北京尚学堂科技JAVA基础课程e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}finally{try{if(fis!=null)fis.close();//流对象,使用完后必须关闭!!}catch(IOExceptione){e.printStackTrace();}}升级为:staticvoidtestInputStream(){FileInputStreamfis=null;try{fis=newFileInputStream("d:/1005班/a.txt");StringBuildersb=newStringBuilder();inttemp=0;byte[]buf=newbyte[1024];while((temp=fis.read(buf))!=-1){//!=-1Stringstr=newString(buf,0,temp);sb.append(str);}System.out.print(sb.toString());331 北京尚学堂科技JAVA基础课程}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}finally{try{if(fis!=null){fis.close();}}catch(IOExceptione){e.printStackTrace();}}}Java中流的概念细分流的方向:输入流:数据源到程序(InputStream、Reader读进来)输出流:程序到目的地(OutPutStream、Writer写出去)处理数据单元:字节流:按照字节读取数据(InputStream、OutputStream)字符流:按照字符读取数据(Reader、Writer)功能不同:节点流:可以直接从数据源或目的地读写数据。处理流:不直接连接到数据源或目的地,是处理流的流。通过对其他流的处理提高程序的性能。331 北京尚学堂科技JAVA基础课程注:节点流和处理流的关系:节点流处于io操作的第一线,所有操作必须通过他们进行;处理流可以对节点流也可以对其他处理流进行包装,提高性能或提高程序的灵活性。Java中IO流类的体系注:这里只列出常用的类,详情可以参考JDKAPI文档。粗体标注为最常用,必须掌握的!331 北京尚学堂科技JAVA基础课程四个IO基本抽象类InputStream此抽象类是表示字节输入流的所有类的超类。InputSteam是一个抽象类,它不可以实例化。数据的读取需要由它的子类来实现。根据节点的不同,它派生了不同的节点流子类。继承自InputSteam的流都是用于向程序中输入数据,且数据的单位为字节(8bit);下图中深色为节点流,浅色为处理流。常用方法:read,close.详情可以参考API文档。OutputStream此抽象类是表示输出字节流的所有类的超类。输出流接受输出字节并将这些字节发送到某个接收器。常用InputStream和OutputStream子类用法FileInputStream和FileOutputStream构造方法和常用方法:自己参考API文档。FileInputStream用于读取诸如图像数据之类的原始字节流。要读取字符流也就是说,处理文本的话使用字符流。,请考虑使用FileReader。available():并不是指定文件还有多少数据没有读,不然,如果是100g的大文件,返回得数就溢出了。不过,对于普通文件的话可以看做是剩余的未读数据。返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。FileOutputStream用于写入诸如图像数据之类的原始字节的流。要写入字符流,请考虑使用FileWriter。练习:文件读取到内存中:voidtestInputStream(){FileInputStreamfis=null;331 北京尚学堂科技JAVA基础课程StringBuildersb=newStringBuilder();inttemp=0;intnum=0;longdate1=System.currentTimeMillis();try{fis=newFileInputStream("d:/a.txt");//内容是:abc/*while((temp=fis.read())!=-1){sb.append((char)temp);num++;}*///使用数组作为缓存,读取的效率大大提高byte[]buffer=newbyte[1024];while((temp=fis.read(buffer))!=-1){sb.append(newString(buffer,0,temp));}System.out.println(sb);}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}finally{331 北京尚学堂科技JAVA基础课程try{fis.close();}catch(IOExceptione){e.printStackTrace();}newFile("d:"+File.separator+"a.txt");}longdate2=System.currentTimeMillis();System.out.println("耗时:"+(date2-date1));}将字符串/字节数组的内容写入到文件中:FileOutputStreamfos=null;Stringstring="abcdefg";try{fos=newFileOutputStream("d:/a.txt",true);fos.write(string.getBytes());}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}finally{try{fos.close();}catch(IOExceptione){e.printStackTrace();}}331 北京尚学堂科技JAVA基础课程实现文件的复制功能:copyFile("d:/a.txt","d:/b.txt");//b.txt可以不存在。voidcopyFile(Stringsrc,Stringdec){FileInputStreamfis=null;FileOutputStreamfos=null;byte[]buffer=newbyte[1024];//为了提高效率,设置缓存数组inttemp=0;try{fis=newFileInputStream(src);fos=newFileOutputStream(dec);while((temp=fis.read(buffer))!=-1){fos.write(buffer,0,temp);}}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}finally{try{fos.close();}catch(IOExceptione){e.printStackTrace();}try{fis.close();}catch(IOExceptione){331 北京尚学堂科技JAVA基础课程e.printStackTrace();}}}//copy目录下面所有的内容到另一个目录!!!(作业!)publicclassTestCopy{publicstaticvoidmain(String[]args){//1.实现一个文件到另一个文件的copy//2.实现一个目录(目录下面只有文件)到另一个目录的copy//3.实现一个目录(目录下面包含文件和子目录)到另一个目录的copy//4.利用递归,实现将一个目录下面所有的内容copy到另一个目录Filefile=newFile("D:\share\0100_JavaSE\ppt");Filefile2=newFile("e:/tt");copyDir(file,file2);}//负责copy一个目录下面所有的文件和子目录到另一个目录staticvoidcopyDir(Filefile,Filefile2){newFile(file2,file.getName()).mkdir();//copyFile(newFile(file,"22.txt"),newFile(file2,"22.txt"));File[]files=file.listFiles();for(Filef:files){if(f.isDirectory()){331 北京尚学堂科技JAVA基础课程copyDir(f,newFile(file2,file.getName()));}if(f.isFile()){copyFile(f,newFile(newFile(file2,file.getName()),f.getName()));}}}/*将d:/a/下所有的内容copy到e:/tt/*/staticvoidcopyFile(Filesrc,Filedec){FileInputStreamfis=null;FileOutputStreamfos=null;byte[]buffer=newbyte[1024];//为了提高效率,设置缓存数组inttemp=0;try{fis=newFileInputStream(src);fos=newFileOutputStream(dec);while((temp=fis.read(buffer))!=-1){fos.write(buffer,0,temp);}}catch(FileNotFoundExceptione){331 北京尚学堂科技JAVA基础课程e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}finally{try{fos.close();}catch(IOExceptione){e.printStackTrace();}try{fis.close();}catch(IOExceptione){e.printStackTrace();}}}}ByteArrayInutStream和ByteArrayOutputStream(经常用在需要流和数组之间转化的情况!)ByteArrayInputStream包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪read方法要提供的下一个字节。说白了,FileInputStream是把文件当做数据源。ByteArrayInputStream则是把内存中的某个数组当做数据源。ByteArrayOutputStream类实现了一个输出流,其中的数据被写入一个byte数组。缓冲区会随着数据的不断写入而自动增长。可使用toByteArray()和toString()获取数据。ByteArrayOutputStream将一个输出流指向一个Byte数组,但这个Byte数组是ByteArrayOutputStream内部内置的,不需要我们来定义。331 北京尚学堂科技JAVA基础课程注:不需要关闭流的,但是调用close也没有问题,close不做任何事情。因为ByteArrayOutputStream本身操作的是数组,并没有打开文件描述符之类的,所以不需要关闭。简单测试ByteArrayInputStream:ByteArrayInputStreambais=null;StringBuildersb=newStringBuilder();inttemp=0;intnum=0;longdate1=System.currentTimeMillis();try{byte[]b="abcdefghijklmnopqrstuvwxyz".getBytes();//bais=newByteArrayInputStream(b);bais=newByteArrayInputStream(b,2,10);while((temp=bais.read())!=-1){sb.append((char)temp);num++;}System.out.println(sb);System.out.println("读取的字节数:"+num);}finally{try{bais.close();}catch(IOExceptione){e.printStackTrace();331 北京尚学堂科技JAVA基础课程}newFile("d:"+File.separator+"a.txt");}longdate2=System.currentTimeMillis();System.out.println("耗时:"+(date2-date1));将输入流的内容读入到一个数组中返回:byte[]getBytesFromIS(FileInputStreamfis){ByteArrayOutputStreambaos=null;inttemp=0;try{baos=newByteArrayOutputStream();;while((temp=fis.read())!=-1){baos.write(temp);}returnbaos.toByteArray();//从而返回一个包含输入流所有内容的数组}catch(IOExceptione){e.printStackTrace();returnnull;}}BufferedInputStream和BufferedOutputStream这两个流是处理流,通过内部缓存数组来提高操作流的效率。使用BufferedInputStream和BufferedOutputStream实现文件的复制:331 北京尚学堂科技JAVA基础课程voidcopyFile(Stringsrc,Stringdec){FileInputStreamfis=null;BufferedInputStreambis=null;FileOutputStreamfos=null;BufferedOutputStreambos=null;inttemp=0;try{fis=newFileInputStream(src);fos=newFileOutputStream(dec);bis=newBufferedInputStream(fis);bos=newBufferedOutputStream(fos);while((temp=bis.read())!=-1){bos.write(temp);}}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}finally{//增加处理流后,注意流的关闭顺序!“后开的先关闭!”try{bos.close();}catch(IOExceptione){e.printStackTrace();}try{bis.close();}catch(IOExceptione){331 北京尚学堂科技JAVA基础课程e.printStackTrace();}try{fos.close();}catch(IOExceptione){e.printStackTrace();}try{fis.close();}catch(IOExceptione){e.printStackTrace();}}}DataInputStream和DataOutputStream数据流通常在流中写入或读取一个结果时使用,如网络数据传递。DataInputStream和DataOutputStream提供了可以存取与机器无关的所有Java基础类型数据(如:int,double等)的方法。publicclassTestDataStream{publicstaticvoidmain(String[]args){DataOutputStreamdos=null;DataInputStreamdis=null;try{dos=newDataOutputStream(newBufferedOutputStream((new331 北京尚学堂科技JAVA基础课程FileOutputStream("D:\share\0100_JavaSE\ppt\src\8io\data.txt"))));dis=newDataInputStream(newBufferedInputStream(newFileInputStream("D:\share\0100_JavaSE\ppt\src\8io\data.txt")));dos.writeDouble(Math.random());dos.writeBoolean(true);dos.writeInt(10);dos.writeChar("a");dos.writeUTF("中國字");dos.flush();//从文件中直接读取数据System.out.println("double:"+dis.readDouble());System.out.println("boolean:"+dis.readBoolean());System.out.println("int:"+dis.readInt());System.out.println("char:"+dis.readChar());System.out.println("String:"+dis.readUTF());}catch(IOExceptione){e.printStackTrace();}finally{try{dos.close();}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();331 北京尚学堂科技JAVA基础课程}try{dis.close();}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}}ObjectInputStream和ObjectOutputStream见专题文档:java对象的序列化和反序列化。PrintStream通过打印流,可以很方便的输出内容。可以输出到:文件、控制台、甚至网络等。我们常用的System.out就是一个PrintStream。PrintStream ps = null;//通过FileOutputStream,程序内容输出是向文件中打印        ps = new PrintStream(new FileOutputStream(new File("d:"                 + File.separator + "test.txt")));        ps.print("hi ");331 北京尚学堂科技JAVA基础课程        ps.println("nihao");         ps.close() ; Reader用于读取字符流的抽象类,数据单位为字符。Writer写入字符流的抽象类,数据单位为字符。FileReader和FileWriter实现文本文件的copy:写法和使用stream基本一样。只不过,读取时是读取的字符。FileReaderfr=null;FileWriterfw=null;intc=0;try{fr=newFileReader("d:/a.txt");fw=newFileWriter("d:/d.txt");while((c=fr.read())!=-1){fw.write(c);}}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){331 北京尚学堂科技JAVA基础课程e.printStackTrace();}finally{try{fw.close();}catch(IOExceptione){e.printStackTrace();}try{fr.close();}catch(IOExceptione){e.printStackTrace();}}BufferReader和BufferWriter注:实际开发中用的很多,需要大家亲自敲一遍!!使用他们来实现文本文件的复制:FileReaderfr=null;FileWriterfw=null;BufferedReaderbr=null;BufferedWriterbw=null;StringtempString="";try{fr=newFileReader("d:/a.txt");fw=newFileWriter("d:/d.txt");331 北京尚学堂科技JAVA基础课程br=newBufferedReader(fr);bw=newBufferedWriter(fw);while((tempString=br.readLine())!=null){bw.write(tempString);}}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}finally{try{bw.close();}catch(IOExceptione1){e1.printStackTrace();}try{br.close();}catch(IOExceptione1){e1.printStackTrace();}try{fw.close();}catch(IOExceptione){e.printStackTrace();}try{331 北京尚学堂科技JAVA基础课程fr.close();}catch(IOExceptione){e.printStackTrace();}}InputStreamReader和OutputStreamWriter用来实现将字节流转化成字符流。//接受用户的输入BufferedReaderbReader=null;try{System.out.println("名字:");bReader=newBufferedReader(newInputStreamReader(System.in));System.out.println("用户输入:"+bReader.readLine());}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}331 北京尚学堂科技JAVA基础课程JAVA对象的序列化和反序列化为什么需要序列化和反序列化当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。把Java对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为Java对象的过程称为对象的反序列化。对象的序列化主要有两种用途1) 持久化:把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;比如:休眠的实现。以后服务器session管理,hibernate将对象持久化实现。2) 网络通信:在网络上传送对象的字节序列。比如:服务器之间的数据通信,对象传递序列化涉及的类和接口java.io.ObjectOutputStream代表对象输出流,它的writeObject(Objectobj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。只有实现了Serializable接口的类的对象才能被序列化。序列化/反序列化的步骤和实例1.将类Person的实例进行序列化和反序列化:a)Person类实现Serializable接口:331 北京尚学堂科技JAVA基础课程classPersonimplementsSerializable{intage;booleanisMan;Stringname;publicPerson(intage,booleanisMan,Stringname){super();this.age=age;this.isMan=isMan;this.name=name;}}a)通过ObjectOutputStream将Person对象的数据写入到文件中,即序列化。Personperson=newPerson(20,true,"aa");FileOutputStreamfos=null;;ObjectOutputStreamoos=null;//序列化fos=newFileOutputStream("d:/c.txt");oos=newObjectOutputStream(fos);oos.writeObject(person);oos.flush();oos.close();fos.close();331 北京尚学堂科技JAVA基础课程a)通过ObjectInputStream将文件中二进制数据反序列化成Person对象:ObjectInputStreamois=null;FileInputStreamfis=null;//反序列化fis=newFileInputStream("d:/c.txt");ois=newObjectInputStream(fis);Personp=(Person)ois.readObject();System.out.println(p.name);综合的序列化和反序列化练习classPersonimplementsSerializable{intage;booleanisMan;Stringname;publicPerson(intage,booleanisMan,Stringname){super();this.age=age;this.isMan=isMan;this.name=name;}}publicclassTestDataStream{publicstaticvoidmain(String[]args){ObjectInputStreamois=null;331 北京尚学堂科技JAVA基础课程FileInputStreamfis=null;Personperson=newPerson(20,true,"aa");FileOutputStreamfos=null;;ObjectOutputStreamoos=null;try{//序列化fos=newFileOutputStream("d:/c.txt");oos=newObjectOutputStream(fos);oos.writeObject(person);oos.writeObject(newString("cccc"));oos.writeObject(newDate());oos.writeInt(300);oos.writeBoolean(true);oos.flush();//反序列化fis=newFileInputStream("d:/c.txt");ois=newObjectInputStream(fis);Personp=(Person)ois.readObject();Strings=(String)ois.readObject();Datedate=(Date)ois.readObject();inti=ois.readInt();booleanb=ois.readBoolean();System.out.println(p.name);System.out.println(s);System.out.println(date);System.out.println(i);331 北京尚学堂科技JAVA基础课程System.out.println(b);}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}catch(ClassNotFoundExceptione){e.printStackTrace();}finally{try{ois.close();}catch(IOExceptione){e.printStackTrace();}try{fis.close();}catch(IOExceptione){e.printStackTrace();}}}}331 北京尚学堂科技JAVA基础课程JAVA.IO包相关流对象用法总结(尚学堂1002班王鑫)IO中其他常用类File类文件和目录路径名的抽象表示形式。一个File对象可以代表一个文件或目录,但是不是完全对应的。建立File对象不会对文件系统产生影响。具体用法,可以参见第六章中常用类中File类的讲解。331 北京尚学堂科技JAVA基础课程RandomAccessFile注:不作为重点,了解即可!工作中用的不多!用来任意读取文件中某个位置的信息!本知识点工作中用的不多,大家只要知道这个类的作用,以后一旦用到再深入自学亦可。思考作业1.说出本章最基本的四个抽象类?及他们的区别?2.查资料说出,线程间通讯使用哪个IO流?3.读入读出流的数据必须是按照顺序,依次读出吗?如果我想读取某个文件指定位置,如何做到?4.想copy一个文本数据,使用哪些流?如果考虑效率问题,使用那些流较好?5.对象的序列化接口的特点。6.想把一个字节流转化成字符流,使用什么流?7.处理流和节点流如何理解?说说他们的区别?上机作业1.完成课堂所有代码及各知识点测试代码2.完成将一个目录下所有内容copy到另一个指定目录3.实现将一个ArrayList中所有对象读取到某个文件中,然后再反序列化读出。4.合并多个txt文件5.复制大文件时,想办法将复制进度的百分比在控制台打印出提示:每次从文件中读取的字节数累加/文件的总大小。6.对大文件实现分割处理,再将分割处理后的文件合并回大文件7.完成类似windows中的文件(夹)搜索功能8.写出迅雷下载软件(等学完多线程和网络编程后再做)331 北京尚学堂科技JAVA基础课程a)结合作业6,作业5,RandomAccessFile类b)多线程c)网络编程提高课外作业1.自学apachecommons中的io类库!提示:http://commons.apache.org/io/简单学习一下,不需要看具体的api。如果能在google上搜索到中文帮助,可以详细研究一下。2.使用apachecommons的io库,实现如下操作:a)文件(夹)的删除、复制、排序、过滤、文件的读写操作第九章多线程技术基本概念程序Java源程序和字节码文件被称为“程序”(Program),是一个静态的概念。进程执行中的程序叫做进程(Process),是一个动态的概念。q进程是程序的一次动态执行过程,占用特定的地址空间.q每个进程由3部分组成:cpu,data,code。每个进程都是独立的,保有自己的cpu时间,代码和数据,即便用同一份程序产生好几个进程,它们之间还是拥有自己的这3样东西。缺点:内存的浪费,cpu的负担q多任务(Multitasking)操作系统à将CPU时间动态地划分给每个进程,操作系统同时执行多个进程,每个进程独立运行。以进程的观点来看,它会以为自己独占Cpu的使用权q进程的查看qWindows系统:Ctrl+Alt+DelqUnix系统:psortop331 北京尚学堂科技JAVA基础课程线程q线程是进程中一个“单一的连续控制流程”(asinglesequentialflowofcontrol)/执行路径。线程也可以达到同一份程序产生好几个进程的效果,但是不同的线程之间可以有某种程度上的资源共享,所以线程又被称为轻量级进程(lightweightprocess)。qThreadsrunatthesametime,independentlyofoneanotherq一个进程可拥有多个并行的(concurrent)线程q一个进程中的线程共享相同的内存单元/内存地址空间à可以访问相同的变量和对象,而且它们从同一堆中分配对象à通信、数据交换、同步操作q由于线程间的通信是在同一地址空间上进行的,所以不需要额外的通信机制,这就使得通信更简便而且信息传递的速度也更快。线程和进程的区别§每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销。§线程可以看成时轻量级的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。§线程和进程最根本的区别在于:进程作为资源分配的单位,线程是调度和执行的单位§多进程:在操作系统中能同时运行多个任务(程序)§多线程:在同一应用程序中有多个顺序流同时执行§线程是进程的一部分,所以线程有的时候被称为是轻权进程或者轻量级进程。§ 一个没有线程的进程是可以被看作单线程的,如果一个进程内拥有多个进程,进程的执行过程不是一条线(线程)的,而是多条线(线程)共同完成的。§系统在运行的时候会为每个进程分配不同的内存区域,但是不会为线程分配内存(线程所使用的资源是它所属的进程的资源),线程组只能共享资源。那就是说,出了CPU之外(线程在运行的时候要占用CPU资源),计算机内部的软硬件资源的分配与线程无关,线程只能共享它所属进程的资源。进程与程序的区别     331 北京尚学堂科技JAVA基础课程程序是一组指令的集合,它是静态的实体,没有执行的含义。而进程是一个动态的实体,有自己的生命周期。一般说来,一个进程肯定与一个程序相对应,并且只有一个,但是一个程序可以有多个进程,或者一个进程都没有。除此之外,进程还有并发性和交往性。简单地说,进程是程序的一部分,程序运行的时候会产生进程。JAVA中如何实现多线程(重点!!)通过继承Thread类实现多线程Ø在Java中负责线程的这个功能的是Java.lang.Thread这个类Ø可以通过创建Thread的实例来创建新的线程。Ø每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。Ø通过调用Thead类的start()方法来启动一个线程。publicclassTestThreadextendsThread{publicvoidrun(){for(inti=0;i<100;i++){System.out.println(this.getName()+":"+i);}}publicstaticvoidmain(String[]args){TestThreadthread1=newTestThread();thread1.start();TestThreadthread2=newTestThread();thread2.start();}}这种方式的缺点:那就是如果我们的类已经从一个类继承(如小程序必须继承自Applet331 北京尚学堂科技JAVA基础课程类),则无法再继承Thread类通过Runnable接口实现多线程优点:可以同时实现继承。实现Runnable接口方式要通用一些。publicclassTestThread2implementsRunnable{intthreadId;publicTestThread2(intid){super();this.threadId=id;}publicstaticvoidmain(String[]args){Threadthread1=newThread(newTestThread2(1));thread1.start();Threadthread2=newThread(newTestThread2(2));thread2.start();}publicvoidrun(){for(inti=0;i<100;i++){System.out.println(this.threadId+":"+i);}}}331 北京尚学堂科技JAVA基础课程线程状态和sleep/yield/join/stop/destroy方法新生状态用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable)就绪状态处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列,等待系统为其分配CPU。等待状态并不是执行状态,当系统选定一个等待执行的Thread对象后,它就会从等待执行状态进入执行状态,系统挑选的动作称之为“cpu调度”。一旦获得CPU,线程就进入运行状态并自动调用自己的run方法。运行状态在运行状态的线程执行自己的run方法中代码,直到调用其他方法而终止、或等待某资源而阻塞或完成任务而死亡。如果在给定的时间片内没有执行结束,就会被系统给换下来回到等待执行状态。死亡状态死亡状态是线程生命周期中的最后一个阶段。线程死亡的原因有两个。一个是正常运行的线程完成了它的全部工作;另一个是线程被强制性地终止,如通过执行stop或destroy方法来终止一个线程不推荐使用这两个方法。前者会产生异常,后者是强制终止,不会释放锁。Methodstop()&destroy()intheclassThreadisdeprecated。当一个线程进入死亡状态以后,就不能再回到其它状态了。331 北京尚学堂科技JAVA基础课程让一个Thread对象重新执行一次的唯一方法,就是重新产生一个Thread对象。终止线程的典型方法(重要!!!)publicclassTestThreadCiycleimplementsRunnable{Stringname;booleanlive=true;publicTestThreadCiycle(Stringname){super();this.name=name;}publicvoidrun(){inti=0;while(live){System.out.println(name+(i++));}}publicvoidterminate(){live=false;}publicstaticvoidmain(String[]args){TestThreadCiyclettc=newTestThreadCiycle("线程A:");Threadt1=newThread(ttc);//新生状态t1.start();//就绪状态for(inti=0;i<1000;i++){System.out.println(i);331 北京尚学堂科技JAVA基础课程}ttc.terminate();System.out.println("ttcstop!");}}阻塞状态(sleep/yield/join方法)处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。n在阻塞状态的线程不能进入就绪队列。只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续运行。n有三种方法可以暂停Threads执行:1.sleep方法:Sleep时别的线程也不可以访问锁定对象。2.yield方法:让出CPU的使用权,从运行态直接进入就绪态。让CPU重新挑选哪一个线程进入运行状态。3.join方法:当某个线程等待另一个线程执行结束后,才继续执行时,使用join方法。使调用该方法的线程在此之前执行完毕,也就是等待调用该方法的线程执行完毕后再往下继续执行publicclassTestThreadState{publicstaticvoidmain(String[]args){//使用继承方式实现多线程//StateThreadthread1=newStateThread();//thread1.start();//StateThreadthread2=newStateThread();//thread2.start();331 北京尚学堂科技JAVA基础课程System.out.println("爸爸和儿子买烟故事");Threadfather=newThread(newFatherThread());father.start();}}classStateThreadextendsThread{publicvoidrun(){for(inti=0;i<100;i++){System.out.println(this.getName()+":"+i);try{Thread.sleep(2000);}catch(InterruptedExceptione){e.printStackTrace();}Thread.yield();}}}classFatherThreadimplementsRunnable{publicvoidrun(){System.out.println("爸爸想抽烟,发现烟抽完了");System.out.println("爸爸让儿子去买包红塔山");Threadson=newThread(newSonThread());son.start();System.out.println("爸爸等儿子买烟回来");331 北京尚学堂科技JAVA基础课程try{son.join();}catch(InterruptedExceptione){e.printStackTrace();System.out.println("爸爸出门去找儿子跑哪去了");System.exit(1);//结束JVM。如果是0则表示正常结束;如果是非0则表示非正常结束}System.out.println("爸爸高兴的接过烟开始抽,并把零钱给了儿子");}}classSonThreadimplementsRunnable{publicvoidrun(){System.out.println("儿子出门去买烟");System.out.println("儿子买烟需要10分钟");try{for(inti=1;i<=10;i++){System.out.println("第"+i+"分钟");Thread.sleep(1000);}}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("儿子买烟回来了");}}331 北京尚学堂科技JAVA基础课程线程基本信息和优先级别方法功能isAlive()判断线程是否还“活”着,即线程是否还未终止。getPriority()获得线程的优先级数值setPriority()设置线程的优先级数值setName()给线程一个名字getName()取得线程的名字currentThread()取得当前正在运行的线程对象,也就是取得自己本身publicclassThreadTest3{publicstaticvoidmain(String[]argc)throwsException{Runnabler=newThread6();Threadt=newThread(r,"Nametest");t.start();System.out.println("nameis:"+t.getName());Thread.currentThread().sleep(5000);System.out.println(t.isAlive());System.out.println("over!");}}classThread6implementsRunnable{publicvoidrun(){for(inti=0;i<100;i++)331 北京尚学堂科技JAVA基础课程System.out.println(i);}}nJava提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程。线程调度器按照线程的优先级决定应调度哪个线程来执行。n线程的优先级用数字表示,范围从1到10一个线程的缺省优先级是5qThread.MIN_PRIORITY=1qThread.MAX_PRIORITY=10qThread.NORM_PRIORITY=5n使用下述线方法获得或设置线程对象的优先级。qintgetPriority();voidsetPriority(intnewPriority);注意:优先级低只是意味着获得调度的概率低。并不是绝对先调用优先级高后调用优先级低的线程。publicclassThreadTest4{publicstaticvoidmain(String[]args){Threadt1=newThread(newThread7(),"t1");Threadt2=newThread(newThread7(),"t2");t1.setPriority(1);t2.setPriority(10);t1.start();t2.start();}}331 北京尚学堂科技JAVA基础课程classThread7extendsThread{publicvoidrun(){for(inti=0;i<20;i++){System.out.println(Thread.currentThread().getName()+":"+i);//yield();}}}线程同步和死锁问题问题:/***测试同步问题*@authorAdministrator**/publicclassTestSync{publicstaticvoidmain(String[]args){Accounta1=newAccount(100,"高");Drawingdraw1=newDrawing(80,a1);Drawingdraw2=newDrawing(80,a1);draw1.start();//你取钱draw2.start();//你老婆取钱}}331 北京尚学堂科技JAVA基础课程/**简单表示银行账户*/classAccount{intmoney;Stringaname;publicAccount(intmoney,Stringaname){super();this.money=money;this.aname=aname;}}/***模拟提款操作*@authorAdministrator**/classDrawingextendsThread{intdrawingNum;//取多少钱Accountaccount;//要取钱的账户intexpenseTotal;//总共取的钱数publicDrawing(intdrawingNum,Accountaccount){super();this.drawingNum=drawingNum;this.account=account;}331 北京尚学堂科技JAVA基础课程@Overridepublicvoidrun(){if(account.money-drawingNum<0){return;}try{Thread.sleep(1000);//判断完后阻塞。其他线程开始运行。}catch(InterruptedExceptione){e.printStackTrace();}account.money-=drawingNum;expenseTotal+=drawingNum;System.out.println(this.getName()+"--账户余额:"+account.money);System.out.println(this.getName()+"--总共取了:"+expenseTotal);}}结果:Thread-0--账户余额:20Thread-1--账户余额:-60Thread-0--总共取了:80Thread-1--总共取了:80331 北京尚学堂科技JAVA基础课程由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问。  由于我们可以通过private关键字来保证数据对象只能被方法访问,所以我们只需针对方法提出一套机制,这套机制就是synchronized关键字,它包括两种用法:synchronized方法和synchronized块 1.synchronized方法:通过在方法声明中加入synchronized关键字来声明synchronized方法。如:  publicsynchronized同步的方法必须获得对象的锁才能运行。普通方法不获得锁也可以运行。voidaccessVal(intnewVal);synchronized方法控制对类成员变量的访问:每个对象对应一把锁,每个synchronized方法都必须获得调用该方法的对象的锁方能执行跟synchronize(this)意思差不多。,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。 synchronized方法的缺陷:若将一个大的方法声明为synchronized将会大大影响效率,典型地,若将线程类的方法run()声明为synchronized,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何synchronized方法的调用都永远不会成功。当然我们可以通过将访问类成员变量的代码放到专门的方法中,将其声明为synchronized,并在主方法中调用来解决这一问题,但是Java为我们提供了更好的解决办法,那就是synchronized块。2.synchronized块:通过synchronized关键字来声明synchronized块。语法如下:  synchronized(syncObject)  {  //允许访问控制的代码  }/***测试同步问题*@authorAdministrator**/publicclassTestSync{publicstaticvoidmain(String[]args){331 北京尚学堂科技JAVA基础课程Accounta1=newAccount(100,"高");Drawingdraw1=newDrawing(80,a1);Drawingdraw2=newDrawing(80,a1);draw1.start();//你取钱draw2.start();//你老婆取钱}}/**简单表示银行账户*/classAccount{intmoney;Stringaname;publicAccount(intmoney,Stringaname){super();this.money=money;this.aname=aname;}}/***模拟提款操作*@authorAdministrator**/classDrawingextendsThread{331 北京尚学堂科技JAVA基础课程intdrawingNum;//取多少钱Accountaccount;//要取钱的账户intexpenseTotal;//总共取的钱数publicDrawing(intdrawingNum,Accountaccount){super();this.drawingNum=drawingNum;this.account=account;}@Overridepublicvoidrun(){draw();}voiddraw(){synchronized(account)需要拿到account对象的锁,才能运行。{if(account.money-drawingNum<0){return;}try{Thread.sleep(1000);//判断完后阻塞。其他线程开始运行。}catch(InterruptedExceptione){e.printStackTrace();}account.money-=drawingNum;expenseTotal+=drawingNum;}System.out.println(this.getName()+"--账户余额:"+account.money);331 北京尚学堂科技JAVA基础课程System.out.println(this.getName()+"--总共取了:"+expenseTotal);}}上面这种方式叫做:互斥锁原理。利用互斥锁解决临界资源问题。死锁及解决方案classLipstick{}classMirror{}classMakeupextendsThread{intflag;Stringgirl;staticLipsticklipstick=newLipstick();staticMirrormirror=newMirror();注意是static。这样才能使两个线程得到的是同一个数据@Overridepublicvoidrun(){//TODOAuto-generatedmethodstubdoMakeup();}331 北京尚学堂科技JAVA基础课程voiddoMakeup(){if(flag==0){synchronized(lipstick){System.out.println(girl+"拿着口红!");try{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}synchronized(mirror){System.out.println(girl+"拿着镜子!");}}}else{synchronized(mirror){System.out.println(girl+"拿着镜子!");try{Thread.sleep(2000);}catch(InterruptedExceptione){e.printStackTrace();}synchronized(lipstick){System.out.println(girl+"拿着口红!");}}331 北京尚学堂科技JAVA基础课程}}}publicclassTestDeadLock{publicstaticvoidmain(String[]args){Makeupm1=newMakeup();m1.girl="大丫";m1.flag=0;Makeupm2=newMakeup();m2.girl="小丫";m2.flag=1;m1.start();m2.start();}}如何解决死锁问题:1.往往是程序逻辑的问题。需要修改程序逻辑。2.尽量不要同时持有两个对象锁。如修改成如下:voiddoMakeup(){if(flag==0){synchronized(lipstick){System.out.println(girl+"拿着口红!");try{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}331 北京尚学堂科技JAVA基础课程}synchronized(mirror){System.out.println(girl+"拿着镜子!");}不放在上面同步块里面。不同时持有两个锁。}else{synchronized(mirror){System.out.println(girl+"拿着镜子!");try{Thread.sleep(2000);}catch(InterruptedExceptione){e.printStackTrace();}}synchronized(lipstick){System.out.println(girl+"拿着口红!");}}}}同步是一种解决问题的思路,结合前面卫生间的示例,互斥方式解决多线程的原理是,当一个人进入到卫生间内部时,别的人只能在外部时刻等待,这样就相当于别的人虽然没有事情做,但是还是要占用别的人的时间,浪费系统的执行资源。而同步解决问题的原理是,如果一个人进入到卫生间内部时,则别的人可以去睡觉,不占用系统资源,而当这个人从卫生间出来以后,把这个睡觉的人叫醒就是wait,notify的应用。,则它就可以使用临界资源了。所以使用同步的思路解决多线程问题更加有效,更加节约系统的资源。331 北京尚学堂科技JAVA基础课程生产者/消费者模式 在常见的多线程问题解决中,同步问题的典型示例是“生产者-消费者”模型,也就是生产者线程只负责生产,消费者线程只负责消费,在消费者发现无内容可消费时则睡觉同步解决问题的另一种典型方式:生产者/消费者生产者和消费者共享了SyncStack对象。一个从里面拿东西,一个从里面消费东西。CCCC知识点模式: 在常见的多线程问题解决中,同步问题的典型示例是“生产者-消费者”模型,也就是生产者线程只负责生产,消费者线程只负责消费,在消费者发现无内容可消费时则睡觉。下面举一个例子。publicclassTestProduce{publicstaticvoidmain(String[]args){SyncStacksStack=newSyncStack();Shengchansc=newShengchan(sStack);Xiaofeixf=newXiaofei(sStack);sc.start();xf.start();}}classMantou{intid;Mantou(intid){this.id=id;}}classSyncStack{intindex=0;331 北京尚学堂科技JAVA基础课程Mantou[]ms=newMantou[10];publicsynchronizedvoidpush(Mantoum){while(index==ms.length){try{this.wait();//wait后,线程会将持有的锁释放。sleep是即使睡着也持有互斥锁。}catch(InterruptedExceptione){e.printStackTrace();}}this.notify();//唤醒在当前对象等待池中等待的第一个线程。notifyAll叫醒所有在当前对象等待池中等待的所有线程。//如果不唤醒的话。以后这两个线程都会进入等待线程,没有人唤醒。ms[index]=m;index++;}publicsynchronizedMantoupop(){while(index==0){try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}}this.notify();index--;returnms[index];331 北京尚学堂科技JAVA基础课程}}classShengchanextendsThread{SyncStackss=null;publicShengchan(SyncStackss){//TODOAuto-generatedconstructorstubthis.ss=ss;}@Overridepublicvoidrun(){//TODOAuto-generatedmethodstubfor(inti=0;i<20;i++){System.out.println("造馒头:"+i);Mantoum=newMantou(i);ss.push(m);}}}classXiaofeiextendsThread{SyncStackss=null;publicXiaofei(SyncStackss){//TODOAuto-generatedconstructorstubthis.ss=ss;}331 北京尚学堂科技JAVA基础课程@Overridepublicvoidrun(){//TODOAuto-generatedmethodstubfor(inti=0;i<20;i++){Mantoum=ss.pop();System.out.println("吃馒头:"+i);}}}线程回顾总结New:创建好线程对象,但没有启动的时候.一个线程调用start()之后不一定会马上启动,此时进入就绪状态,等待得到资源.就绪线程序通过Scheduler(调度程序)去确定是否运行.Runing---dead:运行结束(非双向,为单向箭头)Runing---就绪:暂停(除了没有CPU,具备运行的所有条件)331 北京尚学堂科技JAVA基础课程Runing-otherwise(阻塞):因程序原因:调用sleep或join之后,线程被阻塞.这时不具备运行的条件,此时线程进入阻塞池.sleep或join条件解除之后直接进入Runnable不进入running.Lockpool:锁池状态。每个对象都有自己的锁池,锁池里放置了想获得对象锁的线程。等待状态(waitpool):比如一个线程调用了某个对象的wait()方法,就进入了该对象的waitpool,正在等待其它线程调用这个对象的notify()或者notifyAll()(这两个方法同样是继承自Object类)方法来唤醒它;任务调度(补充内容,了解即可!)通过javatimertimetask:(spring的任务调度就是通过他们来实现的)课外知识:使用开源框架quartz实现任务调度在这种实现方式中,Timer类实现的是类似闹钟的功能,也就是定时或者每隔一定时间触发一次线程。其实,Timer类本身实现的就是一个线程,只是这个线程是用来实现调用其它线程的。而TimerTask类是一个抽象类,该类实现了Runnable接口,所以按照前面的介绍,该类具备多线程的能力。        在这种实现方式中,通过继承TimerTask使该类获得多线程的能力,将需要多线程执行的代码书写在run方法内部,然后通过Timer类启动线程的执行。        在实际使用时,一个Timer可以启动任意多个TimerTask实现的线程,但是多个线程之间会存在阻塞。所以如果多个线程之间如果需要完全独立运行的话,最好还是一个Timer启动一个TimerTask实现。java.util.Timer的使用:publicclassTestTimer{publicstaticvoidmain(String[]args){Timert1=newTimer();MyTasktask1=newMyTask();//t1.schedule(task1,3000);//3秒后执行t1.schedule(task1,5000,1000);//5秒以后每隔1秒执行一次!//GregorianCalendarcalendar1=new331 北京尚学堂科技JAVA基础课程GregorianCalendar(2010,0,5,14,36,57);//注意月份是0-11//t1.schedule(task1,calendar1.getTime());//指定时间定时执行}}classMyTaskextendsTimerTask{publicvoidrun(){for(inti=0;i<100;i++){System.out.println("任务1:"+i);}}}思考作业1.程序、进程、线程的区别和联系?2.JAVA中实现多线程的方式有哪几种?各有什么特点?3.如何终止一个java线程的执行?代码如何写?4.线程状态都有哪几种?他们之间是如何互相转化的?说出转化过程?5.sleep、yield、join方法都有什么区别?6.CPU调度多个线程时,线程优先级低的一定不被调用吗?说出理由。7.多线程编程中,死锁是如何发生的?并写出一个实例。上机作业1.测试课堂代码2.熟悉JAVA中创建线程的两种方式3.终止线程执行代码4.测试:synchronized用法331 北京尚学堂科技JAVA基础课程第十章网络编程基本概念什么是计算机网络把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息,共享硬件、软件、数据信息等资源计算机网络的主要功能Ø资源共享Ø信息传输与集中处理Ø均衡负荷与分布处理Ø综合信息服务(www/综合业务数字网络ISDN)什么是网络通信协议计算机网络中实现通信必须有一些约定即通信协议,对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准。网络通信接口为了使两个结点之间能进行对话,必须在它们之间建立通信工具(即接口),使彼此之间能进行信息交换。接口包括两部分:硬件装置:实现结点之间的信息传送软件装置:规定双方进行通信的约定协议331 北京尚学堂科技JAVA基础课程为什么要分层由于结点之间联系很复杂,在制定协议时,把复杂成份分解成一些简单的成份,再将它们复合起来。最常用的复合方式是层次方式,即同层间可以通信、上一层可以调用下一层,而与再下一层不发生关系。通信协议的分层规定把用户应用程序作为最高层,把物理通信线路作为最低层,将其间的协议处理分为若干层,规定每层处理的任务,也规定每层的接口标准。331 北京尚学堂科技JAVA基础课程³1、物理层(PhysicalLayer)³2、数据链路层(DataLinkLayer)³3、网络层(NetworkLayer)网络层协议的代表包括:IP、IPX、RIP、OSPF等³4、传输层(TransportLayer)传输层协议的代表包括:TCP、UDP、SPX等。³5、会话层(SessionLayer)NetBIOS、ZIP(AppleTalk区域信息协议)等。³6、表示层(PresentationLayer)ASCII、ASN.1、JPEG、MPEG等。³7、应用层(ApplicationLayer)Telnet、FTP、HTTP、SNMP等。数据封装数据拆封331 北京尚学堂科技JAVA基础课程IPIPV4,IPV6端口QQ,msn,迅雷/电驴/360.通过端口,可以在一个主机上运行多个网络应用程序。端口是虚拟的概念,并不是说在主机上真的有若干个端口。URL在WWW上,每一信息资源都有统一的且唯一的地址,该地址就叫URL(UniformResourceLocator),它是WWW的统一资源定位符。URL由4部分组成:协议、存放资源的主机域名、资源文件名和端口号。如果未指定该端口号,则使用协议默认的端口。例如,http协议的默认端口为80。在Java.net包中提供了URL类,该类封装了大量复杂的涉及从远程站点获取信息的细节。TCP协议和UDP协议区别在网络通讯中,TCP方式就类似于拨打电话,使用该种方式进行网络通讯时,需要建立专门的虚拟连接,然后进行可靠的数据传输,如果数据发送失败,则客户端会自动重发该数据。而UDP方式就类似于发送短信,使用这种方式进行网络通讯时,不需要建立专门的虚拟连接,传输也不是很可靠,如果发送失败则客户端无法获得。这两种传输方式都是实际的网络编程中进行使用,重要的数据一般使用TCP方式进行数据传输,而大量的非核心数据则都通过UDP方式进行传递,在一些程序中甚至结合使用这两种方式进行数据的传递。由于TCP需要建立专用的虚拟连接以及确认传输是否正确,所以使用TCP方式的速度稍微慢一些,而且传输时产生的数据量要比UDP稍微大一些。总结:TCP传输数据安全,稳定,效率相对较低。UDP传输数据不安全,效率较高。331 北京尚学堂科技JAVA基础课程TCP协议TCP(TransferControlProtocol)是面向连接的,所谓面向连接,就是当计算机双方通信时必需先建立连接,然后数据传送,最后拆除连接三个过程TCP(TransferControlProtocol)并且TCP在建立连接时又分三步走:TCP第一步是请求端(客户端)发送一个包含SYN即同步(Synchronize)标志的TCP报文,SYN同步报文会指明客户端使用的端口以及TCP连接的初始序号;第二步,服务器在收到客户端的SYN报文后,将返回一个SYN+ACK的报文,表示客户端的请求被接受,同时TCP序号被加一,ACK即确认(Acknowledgement)。第三步,客户端也返回一个确认报文ACK给服务器端,同样TCP序列号被加一,到此一个TCP连接完成。然后才开始通信的第二步:数据处理。这就是所说的TCP的三次握手(Three-wayHandshake)。根据三次握手的特点,有一种对服务器的攻击叫做SynFlood洪水攻击。UDP协议Socket通信是一种基于tcp协议,建立稳定连接的点对点的通信。这种通信方式实时、快速、安全性高、但是他很占用系统由于是面向连接的。效率低的资源。在网络传输方式上,还有另一种基于UDP协议的通信方式,称为数据报通信方式。在这种方式中,每个数据发送单元被统一封装成数据包的方式,发送方将数据包发送到网络中,数据包在网络中去寻找他的目的地。注:UDP端口和TCP端口是相互独立的。JAVA网络编程Java为了可移植性,不允许直接调用操作系统,而是由java.net包来提供网络功能。Java虚拟机负责提供与操作系统的实际连接。331 北京尚学堂科技JAVA基础课程InetAddress作用:封装计算机的ip地址和DNS(没有端口信息!)特点:这个类没有构造函数。如果要得到对象,只能通过静态方法:getLocalHost,getByName,getAllByName,getAddress,getHostName基本测试代码://使用getLocalHost方法创建InetAddress对象//InetAddressaddr=InetAddress.getLocalHost();//System.out.println(addr.getHostAddress());//返回:192.168.1.110//System.out.println(addr.getHostName());//输出计算机名//根据域名得到InetAddress对象//InetAddressaddr=InetAddress.getByName("www.163.com");//System.out.println(addr.getHostAddress());//返回163服务器的ip:61.135.253.15//System.out.println(addr.getHostName());//输出:www.163.com//根据ip得到InetAddress对象InetAddressaddr=InetAddress.getByName("61.135.253.15");System.out.println(addr.getHostAddress());//返回163服务器的ip:61.135.253.15System.out.println(addr.getHostName());//输出ip而不是域名。如果这个IP地址不存在或DNS服务器不允许进行IP地址和域名的映射,getHostName方法就直接返回这个IP地址。331 北京尚学堂科技JAVA基础课程InetSocketAddress作用:包含IP和端口,常用于SOCKET通信。测试代码:InetSocketAddresssocketAddress=newInetSocketAddress("127.0.0.1",8080);InetSocketAddresssocketAddress2=newInetSocketAddress("localhost",9000);System.out.println(socketAddress.getHostName());System.out.println(socketAddress2.getAddress());URL类IP地址唯一标识了Internet上的计算机,而URL则标识了这些计算机上的资源。类URL代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。为了方便程序员编程,JDK中提供了URL类,该类的全名是java.net.URL,有了这样一个类,就可以使用它的各种方法来对URL对象进行分割、合并等处理。基本方法测试:URLu=newURL("http://www.google.cn:80默认是80端口.可加可不加!一般不加!/webhp#aa?canhu=33");System.out.println("获取与此url关联的协议的默认端口:"+u.getDefaultPort());System.out.println("getFile:"+u.getFile());//端口号后面的内容System.out.println("主机名:"+u.getHost());//www.google.cnSystem.out.println("路径:"+u.getPath());//端口号后,参数前的内容System.out.println("端口:"+u.getPort());//如果www.google.cn:80则返回80.否则返回-1System.out.println("协议:"+u.getProtocol());System.out.println("参数部分:"+u.getQuery());331 北京尚学堂科技JAVA基础课程System.out.println("锚点:"+u.getRef());//System.out.println(u.sameFile(u2));//两个url不同,则返回false.//URLConnectionconn=u.openConnection();//InputStreamis=u.openStream();URLu=newURL("http://www.abc.com/aa/");URLu2=newURL(u,"2.html");//相对路径构建url对象System.out.println(u2.toString());//http://www.abc.com/aa/2.html最简单的网络爬虫:voidbasicSpider(){URLurl=null;InputStreamis=null;BufferedReaderbr=null;StringBuildersb=newStringBuilder();Stringtemp="";try{url=newURL("http://www.baidu.com");is=url.openStream();br=newBufferedReader(newInputStreamReader(is));while((temp=br.readLine())!=null){sb.append(temp);//这样就可以将网络内容下载到本地机器。然后进行数据分析,建立索引。这也是搜索引擎的第一步。}System.out.println(sb);331 北京尚学堂科技JAVA基础课程}catch(MalformedURLExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}finally{try{br.close();}catch(IOExceptione){e.printStackTrace();}try{is.close();}catch(IOExceptione){e.printStackTrace();}}}基于TCP协议的SOCKET编程和通信在网络通讯中,第一次主动发起通讯的程序被称作客户端(Client)程序,简称客户端,而在第一次通讯中等待连接的程序被称作服务器端(Server)程序,简称服务器。一旦通讯建立,则客户端和服务器端完全一样,没有本质的区别。“请求-响应”模式:Socket类:发送TCP消息ServerSocket类:创建服务器套接字是一种进程间的数据交换机制。这些进程既可以在同一机器上,也可以在通过网络连接的不同机器上。换句话说,套接字起到通信端点的作用。331 北京尚学堂科技JAVA基础课程单个套接字是一个端点,而一对套接字则构成一个双向通信信道,使非关联进程可以在本地或通过网络进行数据交换。一旦建立套接字连接,数据即可在相同或不同的系统中双向或单向发送,直到其中一个端点关闭连接。套接字与主机地址和端口地址相关联。主机地址就是客户端或服务器程序所在的主机的ip地址。端口地址是指客户端或服务器程序使用的主机的通信端口。在客户端和服务器中,分别创建独立的Socket,并通过Socket的属性,将两个Socket进行连接,这样,客户端和服务器通过套接字所建立连接使用输入输出流进行通信。TCP/IP套接字是最可靠的双向流协议,使用tcp/ip可以发送任意数量的数据。实际上,套接字只是计算机上已编号的端口。如果发送方和接收方计算机确定好端口,他们就可以通信了。TCP/IP通信连接的简单过程:位于A计算机上的tcp/ip软件向B计算机发送包含端口号的消息,B计算机的TCP/IP软件接收该消息,并进行检查,查看是否有他知道的程序正在该端口上接收消息。如果有,他就将该消息交给这个程序。要使程序有效地运行,就必须有一个客户端和一个服务器。通过Socket的编程顺序:1.创建服务器ServerSocket,在创建时,定义ServerSocket的监听端口(在这个端口接收客户端发来的消息!)2.ServerSocket调用accept()方法,使之处于阻塞状态3.创建客户机Socket,并设置服务器的ip及端口4.客户机发出连接请求,建立连接。5.分别取得服务器和客户端Socket的InputStream和OutputStream6.利用Socket和ServerSocket进行数据传输。典型代码:importjava.io.BufferedReader;importjava.io.BufferedWriter;331 北京尚学堂科技JAVA基础课程importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.ObjectOutputStream;importjava.io.OutputStreamWriter;importjava.net.ServerSocket;importjava.net.Socket;/***最简单的服务器端代码*@authorAdministrator**/publicclassBasicSocketServer{publicstaticvoidmain(String[]args){try{//建立服务器端套接字ServerSocketserverSocket=newServerSocket(8888);//tcp端口一共多少个??//监听,等待客户端请求,并愿意接收连接。System.out.println("服务端建立监听");Socketsocket=serverSocket.accept();//通过流向客户端发送数据//ObjectOutputStreamoos=newObjectOutputStream(socket.getOutputStream());//oos.writeObject("aaaaa");//oos.close();331 北京尚学堂科技JAVA基础课程BufferedWriterbw=newBufferedWriter(newOutputStreamWriter(socket.getOutputStream()));bw.write("hhhh");bw.close();socket.close();}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.ObjectInputStream;importjava.net.InetAddress;importjava.net.Socket;importjava.net.UnknownHostException;/***最简单的Socket客户端*@authorAdministrator**/publicclassBasicSocketClient{331 北京尚学堂科技JAVA基础课程publicstaticvoidmain(String[]args){try{//指定的是所要连接的服务器的ip和端口。而不是自己机器的端口。发送端口是随机的。Socketsocket=newSocket(InetAddress.getLocalHost(),8888);//ObjectInputStreamois=newObjectInputStream(socket.getInputStream());//Stringstring=(String)ois.readObject();//System.out.println(string);BufferedReaderbr=newBufferedReader(newInputStreamReader(socket.getInputStream()));System.out.println(br.readLine());br.close();socket.close();}catch(Exceptione){e.printStackTrace();}}}客户端和服务器端可以双向交流的Socket程序:publicclassServer{publicstaticvoidmain(String[]args)throwsException{ServerSocketserver=newServerSocket(8888);Socketsocket=server.accept();BufferedReaderin=newBufferedReader(newInputStreamReader(socket.getInputStream()));331 北京尚学堂科技JAVA基础课程BufferedWriterout=newBufferedWriter(newOutputStreamWriter(socket.getOutputStream()));BufferedReaderbr=newBufferedReader(newInputStreamReader(System.in));while(true){Stringstr=in.readLine();System.out.println("客户端说:"+str);Stringstr2="";str2=br.readLine();//读到n为止,因此一定要输入换行符!out.write(str2+"n");out.flush();if(str.equals("end"))break;}in.close();out.close();socket.close();}}publicclassClient{staticSocketserver;publicstaticvoidmain(String[]args){try{server=newSocket(InetAddress.getLocalHost(),8888);BufferedReaderin=newBufferedReader(newInputStreamReader(server.getInputStream()));BufferedWriterout=newBufferedWriter(newOutputStreamWriter(server.getOutputStream()));331 北京尚学堂科技JAVA基础课程BufferedReaderwt=newBufferedReader(newInputStreamReader(System.in));while(true){Stringstr=wt.readLine();out.write(str+"n"一定要加。不加的话,那边按照readLine读的话,如果没读到n就会一直阻塞!);out.flush();if(str.equals("end")){break;}System.out.println("服务器发说:"+in.readLine());}out.close();in.close();wt.close();server.close();}catch(UnknownHostExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}331 北京尚学堂科技JAVA基础课程}上面这个程序,必须按照安排好的顺序,服务器和客户端一问一答!不够灵活!!可以使用多线程实现更加灵活的双向通讯!!服务器端:一个线程专门发送消息,一个线程专门接收消息。客户端:一个线程专门发送消息,一个线程专门接收消息。除了消化这段代码外,还需要思考,怎么实现一个聊天室!(难度较大!!)publicclassChatServer{publicstaticvoidmain(String[]args){ServerSocketserver=null;Socketsocket=null;BufferedReaderin=null;try{server=newServerSocket(8888);socket=server.accept();newServerThread(socket).start();//main线程负责读取客户端发来的信息in=newBufferedReader(newInputStreamReader(socket.getInputStream()));while(true){Stringstr=in.readLine();System.out.println("客户端说:"+str);}}catch(IOExceptione){e.printStackTrace();}finally{331 北京尚学堂科技JAVA基础课程try{in.close();}catch(IOExceptione){e.printStackTrace();}try{socket.close();}catch(IOExceptione){e.printStackTrace();}}}}/***专门向客户端发送消息的线程*@authorAdministrator**/classServerThreadextendsThread{Socketss;BufferedWriterout;BufferedReaderbr;publicServerThread(Socketss){this.ss=ss;try{331 北京尚学堂科技JAVA基础课程out=newBufferedWriter(newOutputStreamWriter(ss.getOutputStream()));br=newBufferedReader(newInputStreamReader(System.in));}catch(IOExceptione){e.printStackTrace();}}publicvoidrun(){try{while(true){Stringstr2=br.readLine();out.write(str2+"n");out.flush();}}catch(IOExceptione){e.printStackTrace();}finally{try{out.close();}catch(IOExceptione){e.printStackTrace();}try{br.close();}catch(IOExceptione){e.printStackTrace();}331 北京尚学堂科技JAVA基础课程}}}publicclassChatClient{publicstaticvoidmain(String[]args){Socketsocket=null;BufferedReaderin=null;try{socket=newSocket(InetAddress.getByName("192.168.1.32"),8888);newClientThread(socket).start();in=newBufferedReader(newInputStreamReader(socket.getInputStream()));//main线程负责接收服务器发来的信息while(true){System.out.println("服务器说:"+in.readLine());}}catch(UnknownHostExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}finally{try{socket.close();331 北京尚学堂科技JAVA基础课程}catch(IOExceptione){e.printStackTrace();}try{in.close();}catch(IOExceptione){e.printStackTrace();}}}}/***用于向服务器发送消息*@authorAdministrator**/classClientThreadextendsThread{Sockets;BufferedWriterout;BufferedReaderwt;publicClientThread(Sockets){this.s=s;try{out=newBufferedWriter(newOutputStreamWriter(s.getOutputStream()));331 北京尚学堂科技JAVA基础课程wt=newBufferedReader(newInputStreamReader(System.in));}catch(IOExceptione){e.printStackTrace();}}publicvoidrun(){try{while(true){Stringstr=wt.readLine();out.write(str+"n");out.flush();}}catch(IOExceptione){e.printStackTrace();}finally{try{wt.close();}catch(IOExceptione){e.printStackTrace();}try{out.close();}catch(IOExceptione){e.printStackTrace();}}}331 北京尚学堂科技JAVA基础课程}UDP通讯的实现DatagramSocket:用于发送或接收数据包当服务器要向客户端发送数据时,需要在服务器端产生一个DatagramSocket对象,在客户端产生一个DatagramSocket对象。服务器端的DatagramSocket将DatagramPacket发送到网络上,然后被客户端的DatagramSocket接收。DatagramSocket有两种构造函数。一种是无需任何参数的,常用于客户端。另一种需要指定端口构造DatagramSocket对象时,封装的是自己的端口号,目的地信息是由数据包对象指定的。,常用于服务器。常用方法:send,receive,closeDatagramPacket:数据容器(封包)的作用常用方法:构造函数、getAddrress(获取发送或接收方计算机的Ip地址)、getData(获取发送或接收的数据),setData(设置发送的数据)UDP通信编程基本步骤:1.创建客户端的DatagramSocket,创建时,定义客户端的监听端口2.创建服务器端的DatagramSocket,创建时,定义服务器端的监听端口3.在服务器端定义DatagramPacket对象,封装待发送的数据包。4.服务器端将数据包发送出去5.客户端接收数据包好像反了?客户端向服务器端发送信息:(最基本的操作)publicclassClient{publicstaticvoidmain(String[]args)throwsException{byte[]b="aaaa".getBytes();//必须告诉数据包要发到哪里去DatagramPacketdp=newDatagramPacket(b,b.length,newInetSocketAddress("localhost",8999));//我本身占用9000端口向外面机器发数据包DatagramSocketds=newDatagramSocket(9000);331 北京尚学堂科技JAVA基础课程ds.send(dp);ds.close();}}publicclassServer{publicstaticvoidmain(String[]args)throwsException{DatagramSocketds=newDatagramSocket(8999);byte[]b=newbyte[1024];DatagramPacketdp=newDatagramPacket(b,b.length);ds.receive(dp);//阻塞式方法Stringstring=newString(dp.getData(),0,dp.getLength());//dp.getLength()返回实际收到的数据的字节数System.out.println(string);ds.close();}}通过ByteArrayInputStream、ByteArrayOutputStream可以传递基本类型数据:publicclassClient{publicstaticvoidmain(String[]args)throwsException{longn=2000L;ByteArrayOutputStreambos=newByteArrayOutputStream();DataOutputStreamdos=newDataOutputStream(bos);dos.writeLong(n);byte[]b=bos.toByteArray();//必须告诉数据包要发到哪里去331 北京尚学堂科技JAVA基础课程DatagramPacketdp=newDatagramPacket(b,b.length,newInetSocketAddress("localhost",8999));//我本身占用9000端口向外面机器发数据包DatagramSocketds=newDatagramSocket(9000);ds.send(dp);ds.close();}}publicclassServer{publicstaticvoidmain(String[]args)throwsException{DatagramSocketds=newDatagramSocket(8999);byte[]b=newbyte[1024];DatagramPacketdp=newDatagramPacket(b,b.length);ds.receive(dp);//阻塞式方法ByteArrayInputStreambis=newByteArrayInputStream(dp.getData());DataInputStreamdis=newDataInputStream(bis);System.out.println(dis.readLong());ds.close();}}传递对象时的情况:classPersonimplementsSerializable{intage;Stringname;publicPerson(intage,Stringname){331 北京尚学堂科技JAVA基础课程super();this.age=age;this.name=name;}}publicclassClient{publicstaticvoidmain(String[]args)throwsException{Personperson=newPerson(20,"aa");ByteArrayOutputStreambos=newByteArrayOutputStream();ObjectOutputStreamoos=newObjectOutputStream(bos);oos.writeObject(person);byte[]b=bos.toByteArray();//必须告诉数据包要发到哪里去DatagramPacketdp=newDatagramPacket(b,b.length,newInetSocketAddress("localhost",8999));//我本身占用9000端口向外面机器发数据包DatagramSocketds=newDatagramSocket(9000);ds.send(dp);ds.close();}}publicclassServer{publicstaticvoidmain(String[]args)throwsException{331 北京尚学堂科技JAVA基础课程DatagramSocketds=newDatagramSocket(8999);byte[]b=newbyte[1024];DatagramPacketdp=newDatagramPacket(b,b.length);ds.receive(dp);//阻塞式方法ByteArrayInputStreambis=newByteArrayInputStream(dp.getData());ObjectInputStreamois=newObjectInputStream(bis);Personperson=(Person)ois.readObject();System.out.println(person.name);ds.close();}}思考作业1.网络编程的基本分层有哪些?2.数据传输过程中,简述数据的封装和拆封?3.TCP是面向连接的,简述三次握手?4.TCP和UDP的区别?5.InetAddress这个类能否操作端口?6.URL类通过哪个方法获取远程资源的流对象?上机作业(分组完成,3人一组,周末完成)1.利用递归算法实现将163.com主页及主页上的链接地址下载到本地2.查看IO一章中的上机作业、结合多线程,完成迅雷软件的核心代码实现3.查询如何实现屏幕的截图代码,然后,完成远程广播软件(类似netmeeting)331 北京尚学堂科技JAVA基础课程1.完成简单的控制台实现的飞鸽传书2.简单的聊天室系统3.查Google,解决如何通过通过Socket编程传输:图片、音频、视频、对象。331 北京尚学堂科技JAVA基础课程第十一章JAVA多媒体编程字体JAVA中字体控制非常简单。主要类为:1.Java.awt.Font2.java.awt.font.*;//该包下面的一些类字体示例和效果packagecom.bjsxt.test;importjava.awt.Font;importjava.awt.Frame;importjava.awt.Graphics;publicclassTestFontextendsFrame{voidloadFrame(){setSize(300,300);setLocation(50,50);setVisible(true);}331 北京尚学堂科技JAVA基础课程@Overridepublicvoidpaint(Graphicsg){Fontf=newFont("隶书",Font.PLAIN,180);g.setFont(f);g.drawString("尚学堂",100,200);}publicstaticvoidmain(String[]args){newTestFont().loadFrame();}}颜色JAVA中的颜色也采用RGB三原色原理,R表示red红色,G表示green绿色,B表示blue蓝色,他们的值都在0-255之间。通过三原色的混合形成各种颜色。Colorc=newColor(200,100,100);//rgb三原色Colord=Color.blue;//一些常见的颜色,可以通过单词来使用颜色编程示例packagecom.bjsxt.test;importjava.awt.Color;331 北京尚学堂科技JAVA基础课程importjava.awt.Frame;importjava.awt.Graphics;publicclassTestFontextendsFrame{voidloadFrame(){setSize(400,400);setLocation(50,50);setVisible(true);}@Overridepublicvoidpaint(Graphicsg){Colorold=g.getColor();Colorc=newColor(200,100,100);//rgb三原色g.setColor(c);g.drawString("尚学堂",80,80);g.setColor(old);//使用完毕后,我们可以将颜色改回以前的颜色}publicstaticvoidmain(String[]args){newTestFont().loadFrame();}}图形绘制我们可以使用JAVA的图形绘制功能实现绘制各种形状,比如:直线、矩形、椭圆、圆弧和三角形等。也可以实现绘制填充颜色的形状图形。331 北京尚学堂科技JAVA基础课程绘制各种图形示例packagecom.bjsxt.test;importjava.awt.Color;importjava.awt.Frame;importjava.awt.Graphics;publicclassTestFontextendsFrame{voidloadFrame(){setSize(400,400);setLocation(50,50);setVisible(true);}@Overridepublicvoidpaint(Graphicsg){Colorold=g.getColor();Colorc=newColor(200,100,100);//rgb三原色g.setColor(c);g.drawLine(100,100,200,200);//画直线g.drawRect(80,80,100,100);//画矩形g.drawOval(80,80,100,100);//画椭圆。以他的外切矩形为准!331 北京尚学堂科技JAVA基础课程g.setColor(old);//使用完毕后,我们可以将颜色改回以前的颜色}publicstaticvoidmain(String[]args){newTestFont().loadFrame();}}图像处理JAVA支持多种图像格式,包括GIF(GraphicsInterchangeFormat),JPEG(JointPhotographicExpertsGroup)、PNG(PortalbeNewworkGraphics)。JAVA中常用的图像处理类有:1.Image2.ImageIO加载图片示例packagecom.bjsxt.test;importjava.awt.*;publicclassTestFontextendsFrame{331 北京尚学堂科技JAVA基础课程Imageimg=Toolkit.getDefaultToolkit().getImage(TestFont.class.getClassLoader().getResource("images/旺财.gif"));voidloadFrame(){setSize(400,400);setLocation(50,50);setVisible(true);}@Overridepublicvoidpaint(Graphicsg){g.drawImage(img,100,100,null);}publicstaticvoidmain(String[]args){newTestFont().loadFrame();}}工程文件结构运行效果331 北京尚学堂科技JAVA基础课程问题:当我们第一次打开窗口时,图片没有出现。这是由于Toolkit类的一个动态代理问题造成的。需要我们将窗口最小化,再打开即可。图片任意缩放并输出新图片packagecom.bjsxt.test;importjava.awt.Graphics;importjava.awt.Image;importjava.awt.image.BufferedImage;importjava.io.File;importjavax.imageio.ImageIO;/***处理图片的工具类*@authorAdministrator331 北京尚学堂科技JAVA基础课程**/publicclassImageUtil{publicstaticvoidscale(FilesrcFile,Fileresult,intscale,booleanflag){try{BufferedImagesrc=ImageIO.read(srcFile);intwidth=src.getWidth();intheight=src.getHeight();if(flag){//放大图片width=width*scale;height=height*scale;}else{width=width/scale;height=height/scale;}Imageimage=src.getScaledInstance(width,height,Image.SCALE_DEFAULT);BufferedImagetag=newBufferedImage(width,height,BufferedImage.TYPE_INT_RGB);Graphicsg=tag.getGraphics();g.drawImage(image,0,0,null);g.dispose();ImageIO.write(tag,"GIF",result);}catch(Exceptione){e.printStackTrace();331 北京尚学堂科技JAVA基础课程}}publicstaticvoidtoSmall(FilesrcFile,Fileresult,intwidth,intheight){try{BufferedImagesrc=ImageIO.read(srcFile);Imageimage=src.getScaledInstance(width,height,Image.SCALE_DEFAULT);BufferedImagetag=newBufferedImage(width,height,BufferedImage.TYPE_INT_RGB);Graphicsg=tag.getGraphics();g.drawImage(image,0,0,null);g.dispose();ImageIO.write(tag,"GIF",result);}catch(Exceptione){e.printStackTrace();}}publicstaticvoidmain(String[]args){}}使用JMF处理音频和视频JMF意为Java媒体框架(JavaMediaFramework)。该核心框架支持不同媒体(如:音频输出和视频输出)间的时钟同步。它是一个标准的扩展框架,允许用户制作纯音频流和视频流。331 北京尚学堂科技JAVA基础课程JMF实际上是Java的一个类包。JMF2.1.1技术提供了先进的媒体处理能力,从而扩展了Java平台的功能。这些功能包括:媒体捕获、压缩、流转、回放,以及对各种主要媒体形式和编码的支持,如M-JPEG、H.263、MP3、RTP/RTSP(实时传送协议和实时流转协议)、MacromediasFlash、IBM的HotMedia和Beatniks的RichMediaFormat(RMF)等。JMF2.1.1还支持广受欢迎的媒体类型,如Quicktime、MicrosoftsAVI和MPEG-1等。此外,JMF2.1.1软件中包括了一个开放的媒体架构,可使开发人员灵活采用各种媒体回放、捕获组件,或采用他们自己的定制的内插组件.JMF还可以播放视频、读取摄像头数据。如果,大家感兴趣,可以到互联网上查找相关资料。同时,我要告诉大家另外一点。JMF分为两部分:JMFAPI和JMFRTPAPI,前者主要用于捕获、处理、存储和播放媒体,后者主要用于在网络上发送和接收流媒体。也就是说,我们可以通过JMF做一些远程监控、网络视频播放的功能。JMF的下载JMF的windows版本下载地址:http://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/VerifyItem-Start/jmf-2_1_1e-windows-i586.exe?BundledLineItemUUID=A9CJ_hCvJoYAAAEuUPEpGJWP&OrderID=quKJ_hCvqP8AAAEuQvEpGJWP&ProductID=X4zACUFBcakAAAEYzNI5AXis&FileName=/jmf-2_1_1e-windows-i586.exeJMF的安装和配置1.双击下载完成的exe文件,安装JMF。跟安装一般软件一样,点击下一步即可。2.并重启电脑3.在你的项目中,增加JMF安装目录的lib子目录下面的jar包。331 北京尚学堂科技JAVA基础课程使用JMF播放音频文件我们将JMF安装好后,并且将相关jar包拷贝到了项目的classpath下面。那么,就可以开发相关程序了。示例代码:packagecom.bjsxt.test;importjava.awt.Frame;importjava.awt.Graphics;importjavax.media.Manager;importjavax.media.MediaLocator;importjavax.media.Player;publicclassTestSoundextendsFrame{voidloadFrame()throwsException{setSize(400,400);setLocation(50,50);setVisible(true);MediaLocatorlocator=newMediaLocator("file:"+"F:/猪头哥哥.mp3");Playerplayer=Manager.createRealizedPlayer(locator);player.prefetch();//预读文件player.start();//player.close();//player.stop();//表示播放停止.其他方法,大家可以根据资料测试!}331 北京尚学堂科技JAVA基础课程@Overridepublicvoidpaint(Graphicsg){g.drawString("播放猪头哥哥这首歌",100,100);}publicstaticvoidmain(String[]args)throwsException{newTestSound().loadFrame();}}上机作业注意:本章的作业并不作为JAVA基础的基本作业。是为了提高大家的自学能力、查找资料的能力、提高兴趣而设置。如果觉得难度较大,可以不做。下面作业需要分组讨论完成,任选一个即可。1.使用JMF完成一个简单的播放器2.使用JMF读取摄像头数据3.远程屏幕监控(类似netmeeting软件)a)将屏幕数据截图b)按照3/帧每秒的速度向其他机器发送。331 北京尚学堂科技JAVA基础课程331 北京尚学堂科技JAVA基础课程第十二章GUI编程之AWT为什么需要GUI?GUI是什么?我们前面编写的程序命令行的程序,用户的体验度极差。GUI(GraphicsUserInterface)指的是图形用户界面编程,通过GUI编程给用户提供一个可视化的界面方便用户的使用。AWT是什么?抽象窗口工具包(AbstractWindowTookit)是为java程序提供建立图形用户界面(GraphicsUserInterfaceGUI)的工具集。主要包含如下组件:1.用户界面组件2.事件处理模型3.图形图像工具(形状、颜色、字体)4.布局管理器AWT的优势1.最早的JAVAGUI包,内嵌到JDK中,无需引入其他类,功能稳定2.AWT组件都是线程安全的3.界面编程基础.学会AWT,很容易去学swing/SWT等功能较强大的GUI组件.AWT的缺点1.组件的创建完全依赖操作系统实现,导致不同的操作系统下出现不同的外观。说白了,awt的组件是由操作系统绘制的,我们也说awt组件是重量级的组件。这个工具包提供了一套与本地图形界面进行交互的接口。AWT中的图形函数与操作系统所提供的图形函数之间有着一一对应的关系,我们把它称为peers。也就是说,当我们利用AWT来构件图形用户界面的时候,我们实际上是在利用操作系统所提供的图形库。由于不同操作系统的图形库所提供的功能是不一样的,在一个平台上存在的功能在另外一个平台上则可能不存在。为了实现Java语言所宣称的"一次编译,到处运行"的概念,AWT不得不通过牺牲功能来实现其平台无关性,也就是说,AWT所提供的图形功能是各种通用型操作系统所提供的图形功能的交集。由于AWT是依靠本地方法来实现其功能的,我们通常把AWT控件称为重量级控件。331 北京尚学堂科技JAVA基础课程1.线程安全导致运行速度慢2.为了保证程序的可移植性,AWT事实上,它是Sun不推荐使用的,只是为了确保向下兼容和支持Swing。组件集遵循最大公约数原则,即AWT只拥有所有平台上都存在的组件的公有集合。有些常用的组件不支持,比如:表、树、进度条等。字体也只能支持4种。为什么还需要学习AWT?实际开发中使用AWT的情况非常少,但是我们仍然有必要学习AWT。主要原因如下:1.Swing是在AWT基础上构建的,事件模型和一些支持类(形状、颜色、字体)都一样。掌握AWT有利于后面学习SWING.Eclipse不是swing开发的,是swt开发的。2.学习一下GUI编程。事实上,编程思路和其他语言类似。3.学会AWT后,学习SWING或SWTSWT无论是在性能和外观上,都超越了SUN公司提供的AWT和SWING。SWT本身仅仅是Eclipse组织为了开发EclipseIDE环境所编写的一组底层图形界面API非常简单。331 北京尚学堂科技JAVA基础课程AWT各组件的整体关系组件Component是一个具有图形表示能力的对象,可在屏幕上显示,并可与用户进行交互,是没有菜单的AWT组件的抽象父类。封装了如下方法:getComponentAt(intx,inty)getFont()getForeground()getName()getSize()paint(Graphicsg)repaint()update()331 北京尚学堂科技JAVA基础课程setVisible(booleanb)组件的默认的Visible属性是FALSE。setSize(Dimensiond)setName(Stringname)setBounds(intx,inty,intwidhth,intheight)同时设置组件的位置和大小容器容器Container是Component的子类,容器对象本身也是组件,是可以装其他组件容器中可以装普通组件,也快成装容器的组件。AWT中有如下三种容器类型:Panel:就是一个矩形空间,目的就是为其他组件提供空间管理。特点:不能独立存在,必须被添加到其他容器中;布局管理器默认是FlowLayout。Window:可独立存在的顶级窗口.他有两个子类:Frame:常见的窗口。初始化不可见,需要用setVisible(true)设置为可见。默认是BorderLayout布局管理器。Dialog:创建对话框。ScollPanel:增加滚动条用。简单示例1:代码:publicstaticvoidmain(String[]args){331 北京尚学堂科技JAVA基础课程Frameframe=newFrame("HelloAWT!");frame.setBounds(200,200,300,300);Buttonb1=newButton("aaa");TextFieldfield=newTextField();frame.add(field);frame.add(b1);//frame.setLayout(newFlowLayout());//frame.pack();frame.setVisible(true);}效果:后面增加的组建把前面的覆盖了,原因是是布局管理器的问题,它默认是BorderLayout。改为FlowLayout就可以了。将注释代码增加,即变成右边的效果。简单实例2,代码和效果如下://增加Panel容器publicstaticvoidmain(String[]args){Frameframe=newFrame("HelloAWT!");frame.setBounds(200,200,300,300);Panelpanel=newPanel();331 北京尚学堂科技JAVA基础课程frame.add(panel);Buttonb1=newButton("aaa");TextFieldfield=newTextField();panel.add(field);panel.add(b1);frame.setLayout(newFlowLayout());frame.pack();Awt编程经常用pack来讲窗口调整到合适大小。而不是直接指定大小frame.setVisible(true);}布局管理器为什么需要布局管理器?为了使生成的GUI具有良好的平台无关性,awt中提供了布局管理器来管理容器中组件的布局,而不是直接设置组件位置和大小。比如:一个按钮,在windows系统下高10px,宽20px,在linux下可能需要15px,宽25px。这样直接设置的话,就需要这样做大量的调整工作。对于一个组件来说,一般都有一个最佳大小(既没有多余空间,也没有内容被遮挡)调整到既能全部显示自己的信息,又不影响旁边其他的组建。,这个最佳大小一般随平台的不同而不同。如果让程序员手动控制调整这个最佳大小的话,不现实。我们可以使用布局管理器来讲组件的大小调整到最佳大小。程序员要做的只是选择合适的布局管理器即可。FlowLayout布局管理器特点:331 北京尚学堂科技JAVA基础课程从左到右排列容器中的组件,满了后就折到下一行。(跟我们书写习惯差不多)典型代码和实例:publicstaticvoidmain(String[]args){Frameframe=newFrame("HelloAWT!");frame.setBounds(200,200,300,300);for(inti=0;i<10;i++){Buttonb1=newButton("按钮"+i);frame.add(b1);}frame.setLayout(newFlowLayout());Frame默认的布局管理器是BorderLayoutframe.setVisible(true);}BorderLayout布局管理器特点和使用要点:1.将容器区域分为东南西北中五个区域:2.添加组件时需要指定到哪个子区域,默认是Center331 北京尚学堂科技JAVA基础课程1.覆盖问题:如果同一个区域添加多个组件,后面的会覆盖前面的我们可以通过放置5个子容器,子容器中在放置其他组件。这样就可以放置远远超过5个的组建喽!典型代码和示例:publicstaticvoidmain(String[]args){Frameframe=newFrame("HelloAWT!");frame.setLayout(newBorderLayout());frame.setBounds(200,200,300,300);Buttonb1=newButton("按钮"+0);Buttonb2=newButton("按钮"+1);Buttonb3=newButton("按钮"+2);Buttonb4=newButton("按钮"+3);Buttonb5=newButton("按钮"+4);Buttonb55=newButton("按钮"+44);frame.add(b1,BorderLayout.SOUTH);frame.add(b2,BorderLayout.NORTH);frame.add(b3,BorderLayout.CENTER);frame.add(b4,BorderLayout.WEST);frame.add(b5,BorderLayout.EAST);frame.add(b55,BorderLayout.EAST);frame.setVisible(true);覆盖问题}331 北京尚学堂科技JAVA基础课程CardLayout布局管理器特点:1.将容器中所有的组件看做一叠卡片,每次只有最上面的卡片才可见。2.几个常用方法:first,last,previous,next,show代码和示例:publicstaticvoidmain(String[]args){Frameframe=newFrame("HelloAWT!");frame.setBounds(200,200,300,300);CardLayoutlayout=newCardLayout();Panelpanel=newPanel();panel.setLayout(layout);Buttonb1=newButton("按钮"+1);Buttonb2=newButton("按钮"+2);Buttonb3=newButton("按钮"+3);panel.add("a",b1);//不加的话,会抛出异常:java.lang.IllegalArgumentException:cannotaddtolayout:constraintmustbeastringpanel.add("b",b2);panel.add("c",b3);frame.add(panel);//layout.first(panel);layout.last(panel);frame.setVisible(true);}331 北京尚学堂科技JAVA基础课程GridLayout布局管理器特点:1.将容器按照指定行列进行分割,每个网络格大小相同。2.默认从左到右,从上到下添加组件3.当自定义的行数和列数不满足要求,系统会通过计算重新布置网格。如左边例子,当为3*3放10个组件时,会自动变成如下:代码和示例:publicstaticvoidmain(String[]args){Frameframe=newFrame("HelloAWT!");frame.setBounds(200,200,300,300);GridLayoutlayout=newGridLayout(4,3);frame.setLayout(layout);for(inti=0;i<10;i++){Buttonbutton=newButton(i+"");frame.add(button);}frame.setVisible(true);}331 北京尚学堂科技JAVA基础课程GridBagLayout布局管理器特点:功能强大,使用复杂。与GirdLayout不同,GridBagLayout中的组件可以跨越多个网格,并可以设置网格大小互不相同,从而实现更加灵活的窗口效果。知道有这个东东,就行了。用到的机会很渺茫。而且,swing中有个BoxLayout完全可以代替他,并且用法简单。综合应用组件和容器和布局管理器我们实际开发时,大部分都是组件、容器、多个布局管理器的综合应用。简单分析菜单区可先去掉。字体格式等其他格式都先不管,只要布局对就可以了。三个区域:1.显示区2.操作区3.数字区代码和示例(此处代码只作示例用,细节不太好。大家需要自己调整):publicstaticvoidmain(String[]args){331 北京尚学堂科技JAVA基础课程Frameframe=newFrame("简单的计算器");frame.setLocation(100,100);Panelp1=newPanel();Panelp2=newPanel();Panelp3=newPanel();GridLayoutgridLayout=newGridLayout(1,3,2,2);GridLayoutgridLayout2=newGridLayout(4,6,2,2);TextFieldtf=newTextField(30);p1.add(tf);Buttonb1=newButton("Backspace");Buttonb2=newButton("CE");Buttonb3=newButton("C");b1.setForeground(Color.red);b1.setBackground(Color.blue);p2.add(b1);p2.add(b2);p2.add(b3);p2.setLayout(gridLayout);for(inti=1;i<=24;i++){Buttonbtn1=newButton(i+"");//如果有耐心,可以讲那些按钮上的字符手动敲进去p3.add(btn1);}p3.setLayout(gridLayout2);331 北京尚学堂科技JAVA基础课程frame.add(p1,BorderLayout.NORTH);frame.add(p2,BorderLayout.CENTER);frame.add(p3,BorderLayout.SOUTH);frame.pack();frame.setVisible(true);frame.setResizable(false);}AWT事件处理模型问题前面我们的按钮对象,点击以后也不会发生什么事情。就像我们遇到火灾没反应一样。那么,我们需要通过AWT的事件处理模型增加相应的响应。事件处理模型是什么?现实实践中,我们也经常会遇到事件处理的情况。比如:我是监工,你是劳动人民,监视你们劳动,如果不劳动,就抽你。那么,这个过程中,我们来做个分析。1.单位赋予我职责:监工。(监视劳动者是否打盹儿)2.劳动者打了个盹3.这个盹儿,被监工看到了331 北京尚学堂科技JAVA基础课程1.监工走上前去抽你整个过程,我们可以细分一下,有几个对象:劳动者:事件源(EventSource)à可以发生打盹儿,劳动,吃饭这些事件。打个盹儿:事件(Event)监工:事件监听器(EventListener)和事件处理器(Eventhandler)当然,恋爱中,这里的监工可以变成你老婆,劳动者可以变成你。事件可以变成看美女。工作,监工就是老板,劳动者就是你;学习中,监工就是老师,你就是劳动者。总之,这个模式符合所以的事情发生和处理过程。所以,这个过程我们是可以抽象的:1.注册监听器到事件源2.事件源上发生事件(专业点:外部动作触发事件源上的事件)3.将事件传递给监听器(专业点:先生成事件对象,然后将对象作为参数传递给事件监听器)4.监听器调用相应的方法进行事件处理整个过程可以使用下面图形来表示:最简单的事件处理程序我们点击按钮对象,然后进行相应的处理。也符合上面的模式。代码如下:publicclassTest{publicstaticvoidmain(String[]args){331 北京尚学堂科技JAVA基础课程Frameframe=newFrame("测试事件");frame.setBounds(100,100,200,200);Buttonbtn=newButton("点我吧");btn.addActionListener(newTestListener());frame.add(btn);frame.setVisible(true);}}classTestListenerimplementsActionListener{publicvoidactionPerformed(ActionEvente){//TODOAuto-generatedmethodstubSystem.out.println("谁点我!!");}}AWT中事件处理代码编写编写过程1.实现相应的Listener接口,定义一个监听类。并通过重写actionPerformed方法来实现对相应事件的处理。2.在事件源对象上通过add***Listener方法将1中定义的监听类的对象传递进来。331 北京尚学堂科技JAVA基础课程处理过程1.注册TestListener到btn2.点击btn,触发事件,系统自动生成Event对象3.Btn对象将Event对象传递给TestListener对象4.TestListener对象调用他的actionPerformed方法进行相应的处理简化理解上面过程1.注册事件2.发生事件:事件源组件发生事件处理事件:系统自动调用注册到该事件源组件的监听器相应的方法进行对应处理事件和事件源对象事件源:就是我们学过的Compotent组件事件:Event,它是由外部事件触发,由系统自动生成的。常见的有如下事件:低级事件:基于具体的动作的事件。比如:窗口最小化、关闭、失去焦点;键盘按下、松开、单击;鼠标进入、点击、拖放等等。331 北京尚学堂科技JAVA基础课程ComponentEvent:ContainerEvent:WindowEvent:FocusEvent:KeyEvent:MouseEvent:高级事件:不和特定动作关联,而和发生事件的对象关联。比如:ActionEvent:当按钮、菜单项被单击,TextField中按回车。ItemEvent:当用户选中或取消某项TextEvent:当文本框、文本域里面的文本发生改变时触发AdjustmentEvent:调节事件,当滑动条上调节滑块时触发事件和事件监听器接口关系总结331 北京尚学堂科技JAVA基础课程注意:一个组件可以添加多个监听器。你女朋友不光监视你是不是看别的美女,也监视你钱怎么花对不对?你可以接收你女朋友的监视,现在也接受老师我的监视。Event常用的方法测试publicclassTest{staticButtonb2=newButton("按钮二");publicstaticvoidmain(String[]args){Frameframe=newFrame("测试事件");frame.setLayout(newFlowLayout());331 北京尚学堂科技JAVA基础课程frame.setBounds(100,100,200,200);Buttonbtn=newButton("点我吧");btn.addActionListener(newTestListener());frame.add(b2);frame.add(btn);frame.setVisible(true);}}classTestListenerimplementsActionListener{publicvoidactionPerformed(ActionEvente){//TODOAuto-generatedmethodstubSystem.out.println(e.getActionCommand());//就是“点我吧”System.out.println(e.getSource());//返回事件源对象System.out.println(e.getWhen());//返回事件发生的时间System.out.println("谁点我!!");}}测试上面所有的事件WindowEvent事件publicclassTest{publicstaticvoidmain(String[]args){Frameframe=newFrame("测试事件");frame.setLayout(newFlowLayout());331 北京尚学堂科技JAVA基础课程frame.setBounds(100,100,200,200);Buttonbtn=newButton("点我吧");TextFieldfield=newTextField(20);frame.add(btn);frame.add(field);frame.setVisible(true);frame.addWindowListener(newTestListener());}}classTestListenerimplementsWindowListener{publicvoidwindowActivated(WindowEvente){//TODOAuto-generatedmethodstubSystem.out.println("窗口被激活!");}publicvoidwindowClosed(WindowEvente){//TODOAuto-generatedmethodstubSystem.out.println("窗口被关闭");}publicvoidwindowClosing(WindowEvente){//TODOAuto-generatedmethodstubSystem.out.println("用户正在关闭!");331 北京尚学堂科技JAVA基础课程System.exit(0);}publicvoidwindowDeactivated(WindowEvente){//TODOAuto-generatedmethodstubSystem.out.println("窗口失去焦点");}publicvoidwindowDeiconified(WindowEvente){//TODOAuto-generatedmethodstubSystem.out.println("窗口被恢复");}publicvoidwindowIconified(WindowEvente){//TODOAuto-generatedmethodstubSystem.out.println("窗口被最小化");}publicvoidwindowOpened(WindowEvente){//TODOAuto-generatedmethodstubSystem.out.println("窗口初次被打开");}}KeyEventpublicclassTestEvent{331 北京尚学堂科技JAVA基础课程按下、松开、单击publicstaticvoidmain(String[]args){Framef=newFrame();f.setBounds(300,300,200,200);Buttonbutton=newButton("测试");f.add(button);f.setVisible(true);/**一个Component要能够响应键盘事件,必须是可以获得焦点的。而要能够获得焦点,需要满足三个要求,根据Sun的JavaTuturial,是visible,enabled,andfocusable。而Frame不满足此要求,所以不能响应键盘事件.其他的很多组件都是可获得焦点的,比如:Button等。*/f.setVisible(true);f.setFocusable(true);f.setEnabled(true);f.addKeyListener(newMyKeyListener());}}classMyKeyListenerimplementsKeyListener{publicvoidkeyPressed(KeyEvente){//TODOAuto-generatedmethodstubSystem.out.println("按下:"+e.getKeyChar());331 北京尚学堂科技JAVA基础课程//返回字符,比如:"a",按下shift+a返回"A"System.out.println(e.getKeyCode());//返回该键对应的数值if(e.getKeyCode()==KeyEvent.VK_0){System.exit(0);}if(e.isShiftDown()&&(e.getKeyCode()==KeyEvent.VK_1)){System.out.println("按下shift和1");}复合键的处理}publicvoidkeyReleased(KeyEvente){//TODOAuto-generatedmethodstub}publicvoidkeyTyped(KeyEvente){//TODOAuto-generatedmethodstub}}MouseEventmouseClicked:单击组件mouseEntered:鼠标进入组件MouseListener:单击、进入、离开、按下、松开。MouseMotionListener:拖拽、移动MouseInputListener:对应swing组件的:addMouseInutListenerpublicclassTestEventextendsFrame{publicstaticvoidmain(String[]args){TestEventf=newTestEvent();f.setLayout(new331 北京尚学堂科技JAVA基础课程mouseExited:鼠标离开组件mouseReleased:在组件上松开鼠标mousePressed:在组件上按下鼠标包含上面两种监听器的所以动作MouseListener响应mouse点击的  MouseMotionListener响应mouse移动,拖拽等等FlowLayout());f.setBounds(300,300,200,200);f.setVisible(true);f.addMouseListener(newMyMouseListener2());f.addMouseMotionListener(newMyMouseListener3());}}classMyMouseListener3implementsMouseMotionListener{publicvoidmouseDragged(MouseEvente){//TODOAuto-generatedmethodstubSystem.out.println("坐标:("+e.getX()+","+e.getY()+")");}publicvoidmouseMoved(MouseEvente){//TODOAuto-generatedmethodstubSystem.out.println("移动:("+e.getX()+","+e.getY()+")");}331 北京尚学堂科技JAVA基础课程}classMyMouseListener2implementsMouseListener{publicvoidmouseClicked(MouseEvente){//TODOAuto-generatedmethodstubPointp=e.getPoint();System.out.println(p.getX()+"--"+p.getY());//返回点击时的坐标System.out.println("单击");}publicvoidmouseEntered(MouseEvente){//TODOAuto-generatedmethodstubSystem.out.println("进入");}publicvoidmouseExited(MouseEvente){//TODOAuto-generatedmethodstubSystem.out.println("离开");}331 北京尚学堂科技JAVA基础课程publicvoidmousePressed(MouseEvente){//TODOAuto-generatedmethodstubSystem.out.println("按下");}publicvoidmouseReleased(MouseEvente){//TODOAuto-generatedmethodstubSystem.out.println("松开");}}事件适配器为什么需要事件适配器上面写关于Window的事件处理,我们并不是每次都需要对所有事件进行处理,很可能只需要处理某个事件,比如:Close。适配器只是监听器接口的空实现;可以看看源代码。如果某个监听器只有一个方法,就没有必要在定义相应的适配器了。331 北京尚学堂科技JAVA基础课程代码示例:publicclassTest{publicstaticvoidmain(String[]args){Frameframe=newFrame("测试事件");frame.setLayout(newFlowLayout());frame.setBounds(100,100,200,200);Buttonbtn=newButton("点我吧");TextFieldfield=newTextField(20);frame.add(btn);frame.add(field);frame.setVisible(true);frame.addWindowListener(newTestAdapter());}}classTestAdapterextendsWindowAdapter{@OverridepublicvoidwindowClosing(WindowEvente){//TODOAuto-generatedmethodstubSystem.exit(0);}}331 北京尚学堂科技JAVA基础课程事件监听器常见的定义形式1.内部类定义(前面的都是这种形式!)2.匿名内部类(很多时候,事件处理没有复用价值如果有需要复用的代码,通常封装成方法。,只是临时使用一次,所以使用匿名内部类更是一种常用的方法!)frame.addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEvente){//TODOAuto-generatedmethodstubSystem.exit(0);}});AWT其他组件按钮、文本域、文本框、标签、画布等等。菜单的实现特点1.所有菜单类继承的是MenuComponent,而不是Component。2.MenuComponent操作比较单调。只能添加到Frame对象中,只能出现在Frame的顶部,不能使用布局管理器管理。有三个相关类:1.MenuBar:是菜单的根基,只能添加到Frame对象中。2.Menu:菜单,可以添加到MenuBar或其他MenuBar中。3.MenuItem:菜单项,菜单中的“叶子节点”。通常被添加到Menu中,可以增加ActionListener实现相应的操作处理。4.CheckboxMenuItem:可复选的菜单项331 北京尚学堂科技JAVA基础课程代码示例和效果publicstaticvoidmain(String[]args){Frameframe=newFrame("测试事件");frame.setLayout(newFlowLayout());frame.setBounds(100,100,200,200);MenuBarbar=newMenuBar();frame.setMenuBar(bar);Menumenu1=newMenu("文件");Menumenu2=newMenu("编辑");Menumenu3=newMenu("查看");Menumenu4=newMenu("图像");bar.add(menu1);bar.add(menu2);bar.add(menu3);bar.add(menu4);CheckboxMenuItemcmi1=newCheckboxMenuItem("工具箱");CheckboxMenuItemcmi2=newCheckboxMenuItem("颜料盒");cmi1.addItemListener(newItemListener(){publicvoiditemStateChanged(ItemEvente){//选中和取消选中都会触发//TODOAuto-generatedmethodstubSystem.out.println("haha");}});331 北京尚学堂科技JAVA基础课程//MenuItemitem1=newMenuItem("查看位图");//创建菜单项的快捷方式MenuShortcutcut1=newMenuShortcut(KeyEvent.VK_B);//按下:ctr+b,及相当于点击指定菜单项MenuItemitem1=newMenuItem("查看位图",cut1);item1.addActionListener(newActionListener(){publicvoidactionPerformed(ActionEvente){//TODOAuto-generatedmethodstubSystem.out.println("刚刚点击了查看位图!");}});//Menu对象中套Menu对象,可以实现多级菜单!Menusub1=newMenu("缩放");MenuItemsubItem1=newMenuItem("大尺寸");subItem1.setEnabled(false);//可以变为灰色,不能点击!MenuItemsubItem2=newMenuItem("自定义");sub1.add(subItem1);sub1.add(subItem2);menu3.add(cmi1);menu3.add(cmi2);menu3.addSeparator();//这个位置生成分割线331 北京尚学堂科技JAVA基础课程menu3.add(item1);menu3.add(sub1);frame.setVisible(true);}331'