《HEAD FIRST JAVA》第一次回顾和整理
第一章 进入Java的世界(基本概念)
主要介绍了Java的工作原理,发展简史,程序结构和一些简单的语法。学过其他语言的人表示这章完全没有压力。
1, 程序的层次:源文件(source file)->类(class)->方法(methods)。
2, Java里面integer和boolean不相容。
3, 语法与C差不多,不过作者好像一直很反感拿C与Java作比较。
第二章 拜访对象村(类与对象)
一开始用了一个巨冷的故事来阐述面向过程编程与面向对象编程的差别(结果当然是面向对象优胜= =先保留意见吧)。
1, 继承机制使子类可以通过继承父类代码来减少重复代码,覆盖机制使子类在不必改动父类的同时可以选择实现自己的方法。(这个机制太强大了!)
2, 类是绘制对象的蓝图,而对象是已知的事物加上执行的动作。对应着,类包括实例变量(instance variable)和方法(methods)。
3, Java程序执行期间是一组可以相互调用或交流信息的对象,对象之间有着独立性(对象自治)。
4, main()在java里面的作用:测试真正的类和启动Java应用程序。Java是面向对象的编程,所以main()里面基本是不带任何方法的,仅作为测试用和启动用。
第三章 认识变量(primitive主数据类型和引用)
介绍了primitive类型变量和引用变量,并阐述了之前的差别。
1, 变量必须有变量类型,两性类型与类之间有时是共通的,所以一般有着相同的命名规则(如果可能的话,每个单词的首字母都要大些,区分于变量名称的命名:除了第一个单词首字母要小写外,之后的单词的首字母都要大写)。
2, 变量名称必须以字母,_或&开头(不能以数字开头)。
3, 除非加上“f”,否则所有带小数点的值在Java里面都看作double类型。
4, Primitive主数据类型变量值是该值的字节所表示的。
5, 引用变量类似于指针,储存的是引用对象的地址(储存方式)。
6, 圆点运算符(.)表示“取得圆点前面的对象,然后求出该对象在圆点后面的事物”。
7, 当一个对象失去所有的引用变量时,它就完蛋了。
8, 数组是对象,无论它里面装的是不是primitive类型。
第四章 对象的行为(方法操作实例变量)
一开始那张图片,我每次看到都想笑(那货的表情和动作都太到位了= =后面一页的号冷笑话也很强大~)。咳咳,这章主要是围绕对象的方法来阐述一些拓展技巧。
1, 根据传入的实参(arguments)或者对象的实例变量(instance variable)的不同,同一个方法在同类型的不同的对象可以有着不同的表现形式。
2, 实参(arguments)是传给方法的实际值,传入方法后就变成了形参。形参(parameters)与局部变量(local)类似是一样的。改变形参并不改变实参。(跟C一样)传入与返回的参数的值的类型可以隐含地放大或者明确地缩小。
3, 可以从方法里面返回值,声明了返回最好要返回(我敲代码时发觉时声明了返回不返回会报错的,但P78最后一个问题的回答并不是这样的••囧),一般情况下只能返回一个值,但是可以返回一个数组,再深一层的,可以返回ArrayList,换言之,只要你封装好了,可以返回任意数量任意类型的任意变量的任意组合。(这也太强大了吧•••)
4, Java是传值调用(pass by value),如果调用的实参是个引用变量,同样拷贝之。
5, 用setter(mutator)和getter(accessor)进行封装(encapsulation),可以保证对象的实例变量可以通过设置setter来防止被恶搞。(用private设置实例变量,用public来设置setter和getter)这样读取和更改实例变量的效率会变低,不过能够提高程序的抵抗力抗性和恢复力抗性。
6, 实例变量有默认值(整形为0,浮点型为0.0,布尔型为false),局部变量没有默认值,使用前需要初始化。
7, 使用==来比较两个primitive主数据类型或者两个引用是否引用到同一个对象。使用equals()来判断两个对象是否在意义上相等。(关于“在意义上”的概念需要斟酌,目前主要用于比较String类型是否相等)。
第五章 超强力方法(编写程序)
通过设计一个SimpleDotComGame大致地说明了程序设计与实现的步骤。
1, 程序设计的第一步是高层设计,把程序的基本架构抽象出来。(想起了万恶的NS图)
2, 第二步,根据基本架构来构思需要什么对象,需要实现什么类。(这是与面向过程不一样的地方,但某程度上类的方法有点像面向过程中的过程函数的一部分,Java优胜在那强大的类的独立性)。书本上提议开发类的过程是:找出类应该做的事情->列出实例变量和方法->编写方法的伪代码->编写方法的测试用程序->实现类->测试方法->出错或重新设计->邀请辣妹参加庆功派对(= =这什么啊?)
3, 伪码,描述要做什么而不是怎么做的类文字,书上的伪码都是全英文的,压力很大,不过估计以后也要习惯了,因为感觉上计算机方面比较好的书都是外国的。测试码,写在真实码之前(因为真实码都写出来了估计就没动力写测试码了),目的是为了写好真实码之后测试真实码。
4, 书本后面介绍了几个技巧:加强版的for(要先把环境参数调到1.5以上才能用);把字符串转换成整形的Integer.parseInt(String);还有C里面学习过的后递增和break语句。
第六章 使用Java函数库 (认识Java的API)
这章的页数很多,把第五章的游戏排BUG之后又升级到高级版(依然无界面)。之后介绍了Java API的用途和用法。
1,排BUG过程中书本引入了强大ArrayList对象,这个对象很牛地,有着类似数组的简易操作性的同时有着类似链表的动态伸缩性,代价是它耗费的资源多一点。(对于add(index, Object)这个方法,index的值与之前的值不能跳空)
2,制作高级版时,书本用一堆球和杯子加遥控器的组合强调了Java是个面向对象的编程工具。
3,接着写到了一些布尔表达式的运算符,跟C一样,所以没有压力。
4, Java API中类是被包装在包中的;使用是必须使用import或者在出现的每个位置写出全称(除了java.lang包中的类);关于java和javax的趣闻;关于查询API给出了查阅参考书和查阅HTML API文档(真希望能具体点)。
第七章 对象村的优质生活(继承与多态)
我认为继承和覆盖是前十二章里面Java里面最强大的机制,拓展性,独立性,适应性,易改性•••多态什么的就是为了配合这个强大的机制而存在的。
1, 关于方法的继承(inheritance)与覆盖(override),书上说得是很清楚的,子类可以继承父类所有的非私有方法,也可以通过写出同名同参数的方法来覆盖父类的方法。方法调用时,遵循低阶优先原则。关于方法继承,有一点要分辨清楚的,子类继承了父类的方法,与把父类的方法的代码拷贝一份到子类的代码中的意义是不一样的,当其他对象引用该方法时,前者会跳入父类中进行调用,后者会跳入子类中进行调用(因为方法已经被覆盖了)。两者的主要差别是如果两者有着同名的实例变量,方法中又涉及了该实例变量,就会产生不同的结果。即使它们共用同一个实例变量,这点上的模糊也通常会导致方法返回一个跟预想不一样的值或者产生一个预料未及的结果。关于实例变量的继承与覆盖,书上说得一般清楚,所以后来编码这一直弄得我好纠结。现在稍微清晰了一点,但也不保证我的理解是正确的,寄希望于下一本教材吧。上机操作后,我感觉“覆盖”这个概念对于实例变量来说不适用,“继承”还有有那点意思的,若子类里面没有新建同名的实例变量,类似于方法的继承,同样不能理解成把父类的关于实例变量的代码拷贝一份到子类中去,调用时,依然是通过调用父类的实例变量。而当子类中存在父类的同名实例变量时,不会产生覆盖,而且作为两个毫不相干的变量各自独自地存在于所属的类中,调用的时候根据引用的不同来区分。
2, 设计继承树的步骤:找出具有共同属性和行为的对象(用继承来防止子类中出现重复的程序代码)->设计代表共同状态与行为的类 ->决定子类时候需要让某项行为(也就是方法的实现)有着特定不同的运作方式->通过寻找使用共同行为的子类来找出更多抽象化的机会->完成类的继承层次。
3, 判断选择继承还是看作实例变量的方法:“是一个”(IS-A)和“有一个”(HAS-A)。
4, 一些关于方法继承的细节:继承单向性(因而有了IS-A的单向性),父类无法继承子类的方法;子类中可以用super()来引用父类的方法;public类型的成员会被继承,private类型的成员不会被继承;x extends y && y extends z ---> x extends z,就是说,x可以通过z的IS-A测试;继承可以减少重复代码,当要修改方法时,只要父类的参数没有改变,子类都不需要改动就能直接继承;继承定义出共同的协议,也就是说,继承可以确保某个父类之下所有子类都会有父类所持有的全部可继承方法;可以用final来标记类使它或者把里面的实例变量和方法标记成private来拒绝被继承;在不知道父类源代码仅知道其方法关键字的时候,可以通过继承的方法来设计功能有所延展的子类。
5, 多态(polymorphism):当定义一组类的父型时,可以用子型的任何类来填补任何需要或期待父型的位置。换句话说,运用多态时,引用类型可以是实际对象类型的父类,这样的话,参数和返回类型都可以多态化处理。其中有一点是要特别注意的,当一个对象实质是子类但它的引用对象是子类的父类时,虽然它本质是子类但它却不能调用子类中的任何东西,Java看重的是引用类型,也就是说此对象只能引用父型中的东西,但可以通过用子类的强制转换符来把引用转换成子类。
6, 最后谈谈覆盖和重载,子类同名方法未必就能覆盖掉父类的方法:连参数类型和数目都相同时叫覆盖,稍有不同就叫重载。重载之间毫无联系,各自独立存在,JVM会根据参数的差别自行决定调用哪个重载的方法。最后是关于覆盖和重载的一些细节上的区分:覆盖(override),参数必须要一样,其返回类型必须要兼容;不能降低方法的存取权限。重载(overload),返回类型可以不同;不能只改变返回类型(参数在类型和数目上至少要稍有不同);可以更改存取权限(因为相互独立)。
第八章 深入多态(接口与抽象类)
这章继续讨论多态,书上说没有接口活不下去,现在有点体会。Java子类有时候扮演着不同的角色,这时候就需要用到接口了,因为父类只能有一个,但是接口的话就没有这个限制了。
1,抽象类(abstract class):有一些类在理论上是不应该被初始化的,这时候加上abstract关键字可以防止它被new出来。抽象类的作用就是在防止被初始化之余能被继承以维持多态。(书上提到特例:抽象类可以有static成员,目前不明白)。抽象类必须要被extends。
2,抽象的方法:抽象的方法没有实体,因而一定要被覆盖,即必须要实现所有抽象的方法。当声明了一个抽象的方法时,该类必须标记成抽象类(我理解成这是要通过强迫设置子类继承来实现方法的覆盖)。
3,万用类Object:所有类的父类;书上介绍的四个方法:equals(),hashCode(),getClass(),toString();Object的作用是为多态提供一个万能模板,因而同样要注意到Object类型的变量只能做Object类里面的方法,要使用子类的方法,只能通过强制转换符(再次强调Java很注重引用变量的类型:“编译器是根据引用类型来判断有哪些method可以调用,而不是根据Object确实的类型。”);而理所当然地,任何对象都可以使用Object里面的方法。
4,书本再再再次强调了Java很注重引用变量的类型:只能在引用变量的类确实有该方法才能够调用它;把类的公有方法当做是合约的内容,合约是你对其他程序的承诺协议。
5, 接口(interface):本质上是一个公用的且里面都是抽象的方法的抽象类。目的是为了让对象从单一的父子类关系中得到拓展以在保持对象独立性和脉络清晰性的同时得到多重身份。一言蔽之,接口就是为多态而存在的(不知这样说会不会太绝对呢= =)。接口可以跨越不同的继承树进行延展,同一对象也可以接上任意的接口。
第九章 对象的前世今生(构造器与垃圾收集器)
这章的冷笑话和配图是前九章里面最到位的一章,- -吐槽乏力了••正如标题所言,这张说的是构造器(constructors)和垃圾收集器(garbage collection)。
1,关于生存空间和生存周期(life)和作用域(scope)什么的,学过C的表示没有压力。所有的对象生存在堆(heap)中,方法调用和局部变量生存在栈(stack)上,而实例变量是生存在其依附的对象上,即也属于堆中。关于栈,遵循后进先出原则,关于各种引用变量,局部引用变量存在于栈,实例引用变量存在于堆,储存的自然只是存取方式。
2,构造函数(constructor):一项关键特征是它不会有返回类型(包括void),另一项关键特征是它会在对象能后被赋值给引用之前就执行。一些构造函数的应用细节:可以使用构造函数来初始化对象的实例变量,如果有提供默认值的要求,还可以通过重载构造函数来满足,而且最后在无参数的构造函数中设定一个默认值;编译器会帮你自动补全,前提是你没有写任何一个构造函数。
3,构造函数与父类之间的关系,这个确实有点纠结:由于子类都包含了父类的实例变量,所以当子类的继承函数执行前,必须先执行父类的继承函数,直至最后执行Object的构造函数,这个过程成为“构造函数链”(constructor chaining);调用父类的构造函数用super(),调用类中的重载构造函数用this(),而由于super()和this()语法上都要求放在构造函数的第一行,所以它们不能同时使用。
4,关于垃圾收集器的工作机理:当对象失去最后一个引用变量时,它失去存在的意义,等待的就是被回收的命运。关于引用变量的生存周期,局部引用变量生存与方法当中,方法结束,引用就消失;实例引用变量的生存周期与它存在的类的生存周期一样,换句话说,他俩的生死大权在类的引用变量上,死去的方法有“引用永久性的离开它的范围”“引用被赋值到其他的对象中”“直接将引用设定为null”。
第十章 数字很重要(数字和静态)
静态什么的到现在依然不是很理解,很头痛。介绍完静态之后就是一些对数字,格式化,日期等之流的介绍,大概浏览了下。
1, 静态的方法通常是实用的方法,不依赖对象的实例变量(可理解成语句独立性很强,不依赖前后的语句),因而不需要建立对象(并且通常构造函数私有化来阻止用户创建实例)。引用时用类的名字来引用即可。又因为静态方法引用对象的是类,所以静态方法是不可及调用同一个类中的非静态的实例变量(因为无法识别应该调用那个对象的的变量,类似的理由,静态方法也不能调用同一个类中非静态方法),只可以调用静态实例变量(因为同类的对象共享同一个静态实例对象,不存在混淆的问题)
2, 静态变量具有共享的特性,在类被加载时初始化(优先于构造函数,并在所有静态方法开始前初始化)。如果即将运行静态方法前还没有赋初值,自动设为默认值,整形为0,浮点型为0.0,布尔型为false,引用变量为null。
3, Java中的常数:用public static final来修饰,即具有“公用”“免实例”“不变”的特性。
4, final:用于变量时,变量不可改变值(定义时貌似必须初始化);用于方法时,方法无法被覆盖;用于类时,类无法被继承。名副其实的终结者。(注:final的类没必要再定义final的方法,无法继承根本不存在方法被覆盖的问题。)
5, primitive主数据类型的包装:1.5之后有了自动包装和解包(autoboxing),一切都变得很美好。基本可以无视int和Integer的差别了,直接套用就是了,强大无比的实。用性。(目前发现不可套用的是ArrayList中的contains方法,需要用到强制转换符。)后面提到了包装的实用性方法:parseInt(),parseDouble(),booleanValue(),toString()等。
6, 数字的格式化:学过C的表示继续没有压力。%[argument number][flags][width][.precision]type这个写得好专业就收录下来了,其他看书OK。
7, 日期的表示法和计算法:这个看书吧= =(import java.util.Date;import java.util.Calendar)
8, 最后一点,静态的import,这个我觉得作用不大,为少翘一点代码而降低程序的易读性很不划算。
第十一章 有风险的行为(异常处理)
开始介绍如何编写软件,很激动~这章主要说异常处理(exception handling)和MIDI(musical instrument digital interface)播放相关。
1, 异常处理:除了RuntimeException和它的子类(一般是可以在编译阶段排除的语法错误),其他异常(exception)都要进行处理(或者duck掉给调用者处理)。处理方法使用try{}和catch{}语句。(选择性加上finally{},两者至少要有一个。)如果不想在当前处理,可以用throws标识方法来duck给此方法的调用者,调用者也可以进一步duck给上一级调用者。如果连main()函数也ducking,那么JVM就会死掉。一些细节:try的时候遇到异常后立即跳到catch(如果有的话),否则运行finally(如果有的话),之后抛出错误(如果有throws后缀的话);一个try后面可以多个catch,平行关系的异常,可以不管先后顺序,父子关系的异常,子型放在父型之上。
2, MIDI(import javax.sound.midi.;):本身不带有音乐信息,上面带的是如何播放音乐的信息,跟乐谱差不多,所以占用空间很小。播放音乐的层次:Sequencer(播放器)->Sequence(CD盘)->Track(单曲)->MidiEvent(音符)。构建的五个步骤:取得Sequencer并将它打开->创建新的Sequence->从Sequence中创建新的Track->填入MidiEvent并让Sequencer播放->按下play键。然后是各种的方法和各种的参数,各种看书和查阅JAVA API(MIDI的参数表至今没有找到)。
第十二章 看图说故事(图形用户接口)
这章主要介绍了GUI(Graphical User Interface):制作窗口和按钮,简单绘图和贴图,简单的动画等等。
1,JFrame用于创建主框架,通过getContentPane()把JButton,JLabel等其他组件(widget)挂载在上面。(import javax.swing.;其他方法和参数见书本或JAVA API)
2,事件源(event source)本身是个对象(框架,按钮,滚动条等),把用户的操作(点击鼠标,按键等)转换成事件(event),如果当前事件源被一个或若干个监听器(listener)注册,那么它会把事件(event object)当成参数返回到实现了对应的监听接口的对象上面。
3, 通过用子类继承JPanel来挂图和绘图。挂图和绘图在类里面的paintComponent方法里面实现。绘图的时机一般由系统决定,也可以通过repaint()命令来强制马上重绘。
4, 内部类(inner class):唯一绑定在第一个初始化自己的外部类上,绑定后不可更改绑定对象,可以使用外部所有的方法与变量,包括有私有标识的。
5, Thread.sleep()用于短暂挂起线程。(C里面的Sleep()函数••)
6, 监听MIDI文件的方法:注册一个特殊编号的MIDI事件(看作ControllerEvent)插入到MIDI文件上所有含有NOTE ON(第一个参数是144)标志的节拍上,把ControllerEventListener注册到sequence上,最后在带有ControllerEventListener()接口的controlChange(ShortMessage ev)方法上实现监听后的响应工作。
第十三章 运用Swing(Swing)
篇幅比较短的一章,主要介绍了布局管理器(Layout Managers)。
1, 几乎所有组件(Components,或widget)都能够安置其他的组件,除了JFrame之外,交互组件于背景组件的差异不明显(JPanel虽然一般都当做背景来使用,但也可以像按钮一样注册鼠标点选的事件)
2, 布局管理器(Layout Managers):通过一种交互的机制(人机交互,布局层次内部的交互)自主决策组件布局的一类对象。决策时优先遵循自己的布局策略,在不破坏自身布局策略的前提下最大程序上满足用户提出的布局请求(也就是有时候会违反用户的请求)。
3, 书上提到的三大布局管理器:BorderLayout(把背景组件分成东南西北中五个区域,优先分配南北,然后东西,最后剩下的部分为中间),FlowLayout(把组件从左到右地排列,并有自动换行的机制),BoxLayout(把组件从上到下地排列,但不带有自动换行的机制)
4, 剩下的JTextArea,JScrollerPane等的方法和参数等可参看书本。
第十四章 保存对象(序列化和文件输入/输出)
终于到输入输出了,这一章的翻译挺不到位,建议对照英文教材阅读之。
1, Java数据输出的两种方法,只给Java读取的话用序列化(serialization),如果要给其他程序读取或使用,输出纯文本文件。
2, (import java.io;)一般来说,串流(stream)要连接流(connection stream)和链接流(chain stream)两两配合才能有效。其中连接流负责连接到文件,socket等,但因为自身一般只有像输出字节等低级方法,所以要借助较为高级的连接流中的高级方法才能转换成功。
3, 要一个类实现可序列化,需要实现Serializable接口。如果不想某个实例变量被序列化,标记上transient(像网络联机这类随机数据也应该标记transient),考虑到要完整且正确地恢复到原状态(所谓状态,一般就是指实例变量的值),序列化时候需要把与保存对象相关的所有对象形成的网络全部序列化保存(如果网络中有一部分实例变量既没有实现Serializable又没有被标记transient)。
4, 对于纯文件的处理用FileWriter和FileReader,为提高效率,可以选择使用BufferedReader和BufferedWriter
5, 剩下还有关于GUI和IO的很多类很多方法很多参数,参看书本吧。
第十五章 网络联机(网络与线程)
嘛,这章大致介绍了怎么实现网络联机,还是就是一些多线程的细节问题。
1, 聊天程序的工作方式:客户端连接到服务器->服务器建立连接并把客户端架到来并清单中->另外一个用户连接上来->用户A送出信息到聊天服务器上->服务器将信息送给所有的来宾(一开始对最后一步有疑问,参看P488就恍然大悟了)
2, Java不需要注意太多细节的东西就可以架设好网络连接(同时译者提醒读者不要把架设网络想成是太简单的事情- -)
3, (import java.net.*;)建立socket连接,要知道IP地址和TCP的端口号。(本机IP地址为:127.0.0.1)
4, 关于网络串流的读写:读,服务器(server)->Socket输入流->InputStreamReader->BufferedReader->客户端(client)。写,客户端->PrintWriter->Socket输出流->服务器。(不知道为什么中间不加BufferedWriter)
5, 多线程(multithreading):线程(thread)是一种独立的执行空间(a separate call stack),除非是多处理器,否则新线程并不是单独运行的线程,虽然感觉上是这样。
6, 每个thread需要一个任务来执行,一个可以放在执行空间的任务(实现Runnable接口的中的run(),类似于主线程的main()方法)。线程有“新建”“可执行”“执行中”三个状态,而且,一旦线程进入了“可执行”状态后,它会在“可执行”和“执行中”两种状态中不停地切换(除非处于堵塞状态)
7, 线程调度器(the thread scheduler):Java自带的决定什么时候运行哪个线程的一种机制,不受用户的API的控制,所以调度结果无法确定(不同的机器有着不同的执行过程,同一台机器也会有着不同的执行过程)。
8, 可以用sleep()方法来影响调度器,不过作用效果一般没有想象中要好。
9, 并发性问题(concurrency issue):当两个或以上的线程存取单一对象的数据的时候,就有机会发生各种奇怪的错误。为了排除这类问题,使用synchronized(同步化过的)标志对象运行中的那些不可分割的过程,类似于一把锁,锁住了储存数据的方法,使一个对象对这个数据使用完毕之后再允许其他对象使用该数据。
第十六章 数据结构(集合和泛型)
各种集合(collections)(目前在学C++版的数据结构…讨厌的课程)
1, 各种数据结构:TreeSet(有序防重复),HashMap(每个数据都有对应的KEY值),LinkedList(大集合的快速插入和删除中间元素,这效果,有点像链表),HashSet(防重复,可以快速寻找元素),LinkedHashMap(HashMap的升级版,具体看书)。书本的说法是:list对付顺序结构,set注重独一无二的性质,map用key来搜索的专家。
2, 使用System.out.println集合的时候,要覆盖集合元素的类中的public String toString()方法来设定输出的内容。
3, 使用Collection.sort(某集合)方法的时候,要求某集合的元素实现排序化(实现Comparable接口之下的public int Compareto()方法),或者用sort的重载方法sort(某集合,某比较器),当然之前要现实某比较器(Comparator)中的int Compare()方法。
4, 关于泛型(generic):java5.0之后推出的功能,为了实现更好的类型安全性。一般用<T>表示,对于集合,也用<E>来表示(E for element),类型参数会被编译器自动识别和替换<T>或<E>的位置。然后public <T extends Animal>void takeThing(ArrayList<T> list)跟public void takeThing(ArrayList<Animal> list)含义是不一样的。还有,泛型里面的extends和implements其实都是is的意思,但是创造新的关键字会破坏之前的程序,所以没有引用is关键字。
5, 对象相等:包括引用相等性和对象相等性,前者指“堆上同一对象的两个引用”,后者指“堆上的两个不同对象在意义上是相同的”,一般需要的是后者,要实现后者,就必须覆盖从Object继承下来的hashCode()和equals()方法。以HashSet为例,检查两个变量是否相等,首先检查hashCode()的返回是否一样,然后再检查equals()函数的返回是否是true。更加细节的东西:hashCode相同并不能保证对象相同的,因为hashCode使用的是杂凑算法。还有就是覆盖equals()方法是要注意它的参数是Object类型的。
6, TreeSet的元素必须实现Comparable或者在构造的时候用comparator来初始化。
7, 然后是多态的问题:不知出自什么原因,java设计时设定数组的类型检查是在运行使其进行的,而集合的类型检查只在编译时期,所以多态在集合要实现要麻烦些——public void takeAnimal(ArrayList<? extends Animal>animals),注意这里的extends依然和implements一起都是is的意思。
第十七章 发布程序(包,jar存档文件和部署)
文件部署,打包成jar什么的,我希望有懒人工具能帮忙打包。
1, 部署分成:完全在本机的Executable Jar,完全在远程的Servlets和介乎两者之间的JWS(我爱翻译成“巨猥琐”)。
2, 源代码和类文件的分离:源代码放在source,类文件放在classes,使用命令-d(书上说-d懂的自己建立未建立的目录,但貌似我这样做时会提示出错)
3, 打包JAR:首先,确认所有的类文件都在classes目录下,然后在该目录下建立manifest.txt来指定哪个类带有main()方法(Main-Class: **),最后用jar命令打包。(jar –cvmf manifest.txt **.jar *.class)
4, 执行JAR:在cmd下用java –jar *.jar命令来启动,如果自带GUI,在windows环境下可以双击打开。(若打开是被winrar等程序干扰时,打开方式设为jre/bin下的javaw.exe,然后在用regedit打开注册表,在HKEY_CLASSES_ROOT下找到.jar文件的打开方法,在参数中间添加-jar字样)
5, 包:主要用于防止类名称的冲突,关于制作包执行包用包弄JAR等具体命令参看P589左右(懒人表示期待工具)
6, Java web start(JWS):书本介绍较为简单,还夹杂着XML的语言…
第十八章 分布式计算(远程部署的RMI)
终于最后一章了,最后几章的难度明显加大呢,可能是因为最后几章涉及联网什么的,那货其实都可以展开写一本书了。
1, RMI(remote method invocation):一种连接客户端和服务器的技术(有点像socket)。事实上,在某堆上的对象无法进行另外堆上的对象引用,但是利用RMI能够模拟这种感觉。实现需要四个部分:服务器(server),客户端(client),服务器辅助设施(server helper),客户端辅助设施(client helper)。客户端调用客户端辅助设施来模拟调用本机对象的感觉,而实际上客户端辅助设施只是作为代理(proxy),真正实现客户端请求的是服务器。
2, RMI调用方法的过程:客户端对象对辅助设置对象调用方法(已注册的方法)->客户端辅助设施把调用信息打包通过网络送到服务器的辅助设施->服务端的辅助设施解开来自客户端辅助设施的信息,并以此调用真正的服务。
3, 创建RMI远程服务:步骤一:创建Remote接口(继承java.rmi.Remote;生命所有的方法都会抛出RemoteException;确定参数和返回值都是primitive主数据类型或者Serializable);步骤二:实现Remote(实现Remote这个接口;继承UnicastRemoteObject;编写声明RemoteExceiption的无参数构造函数;向RMI registry注册服务);步骤三:用rmic产生stub与skeleton(对实现出的类(不是Remote接口)执行rmic);步骤四:启动RMI registry(调出命令行来启动RMI registry);步骤五:启动远程服务(调用另一个命令行来启动服务)
4, Servlet:servlet是完全放在HTTP WEB服务器上运行的JAVA程序,用于应付用户端没有JAVA虚拟机的情况。创建并执行servlet的步骤:找出可以存放servlet的地方(就是要买个服务器);取得servlets.jar并添加到classpath上(上sun官网挂之);通过extend过HttpServlet来编写servlet的类;编写HTML来调用servlet(我不会••);给服务器设定HTML的网页和servlet。
5, JINI(Java Intelligent Network Infrastructure):传说中一个更加强大的RMI,带有自适应探索(adaptive discovery)和自恢复网络(self-healing networks)。因为很强大,所以书上也没有篇幅去细说。后面是实现方法和一堆堆代码,看得我产生了严重的抵触情绪。
最后是附录AB:beatbox的最终版和十大遗珠之憾。
(非原创)《HEAD FIRST JAVA》第一次回顾和整理
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 第一章 进入Java的世界(基本概念) 主要介绍了Java的工作原理,发展简史,程序结构和一些简单的语法。学过其他...
- 情节回顾:《岁月,爱情的劫数》30 哟嗬!神奇的龙凤饭庄! - 简书 兰天鹏觉得很对不起朋友。 他答应帮朋友买蛋糕...