【自学】Head First Java 10-18章笔记

异常处理

  • finally:try或catch有return语句时,finally也会在执行return之前执行
  • 异常是对象,具有多态性,可只声明或catch父类来处理多个异常;为每类异常单独写多个catch块时,要从子类到父类(从小到大)排catch块
  • 有风险方法的调用方式:try/catch;duck
  • duck:踢皮球式处理异常,自己也声明要抛出相同异常,将捕获到的异常从自己抛出,main()抛出的异常由java虚拟机处理。
  • 异常处理规则:不能没有try;try,catch之间不能有程序;try一定要有catch或finally;只有finally的try必须声明异常

GUI

垃圾中文版丢了关键的一句变得误解:这段本意是要说指向子类的父类引用只能调用二者都有的方法(子类重写),而不能调用自己没有,只有子类有的方法(重载、新定义),就是子类能做的事情比父类多。对比可以看到中文版少了第二个画线句子,这让我一开始以为书写错了,而且中文版第一句标题还把graphics拼写错了,书上面也是错的。。。

 

保存对象

存储状态

实现过Serializable接口的类其对象才能序列化。

将序列化对象写入文件

  • 创建FileOutputStream:FileOutputStream fileStream=new FileOutputStream(“myfile.ser”);
  • 创建ObjectOutputStream:ObjectOutputStream os=new ObjectOutputStream(fileStream);
  • 写对象:os.writeObject( myobject );
  • 关闭ObjectOutputStream:os.close();

读取对象,解序列化

  • 创建FileInputStream:FileInputStream fileStream=new FileInputStream(“myfile.ser”);
  • 创建ObjectInputStream:ObjectInputStream os=new ObjectInputStream(fileStream);
  • 读取对象:Object one=os.readObject(); //readObject()返回值是Object类型
  • 转换对象类型:MyClass  myone=(MyClass) one;
  • 关闭ObjectInputStream:os.close();

写文本文件:FileWriter (打开/建立文件、写入、关闭文件)

  • FileWriter writer=new FileWriter(“myfile.txt”);
  • writer.write(“hello”);
  • writer.close();

读文本文件:FileReader (关联文件、读、关闭文件)

  • File myFile=new File(“MyText.txt”);
  • FileReader fileReader=new FileReader(myFile);
  • BufferedReader reader=new BufferedReader(fileReader);
  • String line=null;
  • while((line= reader.readLine())!=null){  //通常是循环读入
  •          System.out.println(line);
  • }
  • reader.close();

PS:输入输出相关操作都有包含在try/catch块中

缓冲区BufferedWriter, BufferedReader

  • BufferedWriter:BufferedWriter  writer=new BufferedWriter(new FileWriter(aFile));
  • BufferedReader:BufferedReader  reader=new BufferedReader (new File (aFile));

 

File代表磁盘上的文件这个概念,类似于文件路径,而非具体文件的内容。File可用于创建文件对象、新目录(列出目录内容)、取得文件或目录绝对路径、删除文件

socket连接

  • socket是代表两台及其支架网络连接的对象,连接就是两台机器之间的一种关系
  • 客户端通过建立Socket来连接服务器,建立socket连接需要IP地址(或网域名称)和TCP端口号,连接的建立代表双方存有对方的信息(IP,TCP端口号)
  • TCP端口号(16bits):识别服务器上的特定程序
  • InputStreamReader是转换字节成字符的桥梁,注意用来连接BufferedReader与底层的Socket输入串流。

使用串流通过socket连接进行沟通,读服务器数据

  • Socket chat=new Socket (“127.0.0.1”, 5000);
  • InputStreamReader stream=new InputStreamReader (chat.getInputStream());
  • BufferedReader reader=new BufferedReader (stream);
  • String message=reader.readLine ();

PrintWriter连接Socket输出串流写数据给服务器

  • Socket chat=new Socket (“127.0.0.1”,5000);
  • PrintWriter writer=new PrintWriter(chat.getOutputStream());
  • writer.println (“message1”);

编写服务器程序需要一对Socket:等待用户请求的ServerSocket、与用户通信用的Socket

  1. 服务器应用程序对特定端口创建ServerSocket,让应用程序开始监听来自4242端口的客户端请求:ServerSocket serverSock=new ServerSocket(4242);
  2. 客户端对服务器应用程序建立Socket连接:Socket sock=new Socket(“127.0.0.1”,4242);
  3. 服务器创建于客户端通信的新Socket:Socket sock=severSock.accept(); accept()方法只等待用户的Socket连接时处于闲置状态,当用户连上来时,此方法返回一个Socket与客户端通信。Socket与ServerSocket的端口不同,因此ServerSocket可以空出来等待其他用户。

 

线程

  • 线程代表独立的执行空间,记录目前线程空间执行到哪里

启动新线程:

  1. 建立Runnable对象(线程的任务):Runnable threadJob=new myRunnable();
  2. 建立Thread对象(执行者)并赋予Runnable:Thread myThread=new Thread(threadJob);
  3. 启动Thread:myThread.statr();

synchronized关键字修饰的方法具有原子性,一次只能被单一线程存取

死锁:出现了循环等待资源

数据结构

TreeSet

有序、不重复

HashMap

用成对的name/value来保存取出

LinkedList

用于经常删除、插入元素的集合

HashSet

防止重复的集合,可快速找到相符的元素

LinkedHashMap

类似HashMap,但可记住元素插入顺序,可按元素上次存取顺序排序

  • a.equals(b)为true是a,b对象相等的充要条件;hashcode相等是两个对象相等的必要条件
  • a,b对象相等 <=> a.equals(b)==b.equals(a)==true => a.hashCode()==b.hashCode。

HashSet检查重复

把对象加入HashSet时,用hashcode判断对象加入的位置,同时将其与已经加入的对象比较hashcode,相同则表示重复。所以hashCode()必须被覆盖过,因为hashCode()的默认行为是对堆上的对象产生独特的值,如果没有覆盖,则值相同的两个对象无法产生相同的hashcode;equals()也必须被覆盖过,因为equals()的默认行为是执行==比较,即测试两个引用是否指向堆上同一个对象,如果没有覆盖,则两个对象永远不会被视为相等。

public <T extends Animal> void takeThing1 (ArrayList <T>  list1)

  • takeThing1() 方法的参数list1可以是元素为任意Animal及其子类对象的ArrayList

public void takeThing2 (ArrayList <Animal>  list2)

  • takeThing2() 方法的参数list2只能是元素为Animal对象的ArrayList。此时不能用Animal数组的多态思想来考虑Animal的ArrayList,即list2,因为ArrayList还有其他类似于add()的方法,如果给list2赋予的是 Dog的ArrayList,则当takeThing()里面有类似list2.add(new Cat) 的操作时,编译不通过。

通配符<?>:在方法参数中使用通配符时,编译器会阻止任何可能破环引用参数所指集合的行为,即不能加入元素。

另一种等效的类型参数声明方式:在返回类型前声明类型参数

  • public <T extends Animal> void takeThing(ArrayList<T> list)  //与下一句效果一样
  • public void takeThing(ArrayList<? extends Animal> list)

发布程序:JAR、JWS、RMI、Servlet

 

-d:指定存储编译过的文件的路径

JAR文件:把一组类文件包装成pkzip格式。创建带有JAR信息的manifest文件后,程序就可以在类文件保存在JAR的情况下执行

创建可执行的JAR

  1. 确定所有类文件都在classes目录下
  2. 创建manifest.txt来描述那个类带有main()
  3. 执行jar工具来创建带有所有类和manifest的JAR文件

用包创建可执行的JAR

  1. 确定所有类文件都放在class目录下正对相对应的包结构中
  2. 创建manifest.txt文件来描述那个类带有main(),以及确认有使用完整的类名称
  3. 执行jar工具创建带有目录结构与manifest的JAR文件

把类包进包中:在源程序最前面加上包指令package

Java Web Start(JWS)工作方式:

  1. 客户端点击某网页上JWS应用程序的链接( .jnlp文件:描述应用程序可执行JAR文件的XML文件)
  2. Web服务器收到请求发送.jnlp文件给客户端浏览器
  3. 浏览器启动Java Web Start,JWS的helper app读取.jnlp文件,向服务器请求JAR文件
  4. Web服务器发送.jar文件
  5. JWS取得JAR并调用指定main()启动应用程序

远程程序调用Remote Method Invocation,RMI——业界用的不多

  • 客户端和服务器都是与各自的辅助设施打交道,辅助设施之间通过Socket连接传输信息。

客户端调用服务端方法的过程:

  1. 客户端对象对辅助设施对象调用方法
  2. 客服段辅助设施把调用信息打包通过网络送到服务器辅助设施
  3. 服务端的辅助设施解开来自客户端辅助设施的信息,以此调用真正的服务

Java RMI提供客户端辅助设施对象 (stub) 和服务器端的辅助设施对象 (skeleton),提供执行期所需的全部基础设施(感觉像是调用远程对象的方法,但其实不是)。因为辅助设施通过网络发出调用,网络输入/输出有风险,因此使用RMI是必须决定协议:JRMP或IIOP

创建远程服务:

1、创建Remote接口。接口定义了客户端可以调用的方法,stub和服务器都会实现此接口

  • 继承java.rmi.Remote:public interface MyRemote extends Remote
  • 所有声明的方法都要抛出异常RemoteException
  • 确定参数和返回值都是primitive类或Serializable,因为需要打包通过网络序列化传输

2、实现Remote接口。实现出定义在该接口的方法,是真正执行的类,是客户端会调用的对象

  • 实现Remote:public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote
  • 继承UnicastRemoteObject,使对象具有与远程相关的功能
  • 编写声明RemoteExpection的无参构造函数。因为UnicastRemoteObject的构造函数会抛出RemoteExpection,因此在接口实现中也要声明一个构造函数抛出RemoteExpection
  • public MyRemoteImpl() throw RemoteException{ }
  • 用java.rmi.Naming的rebind()向RMI registry注册服务,RMI系统吧stub加到registry中,让远程用户可以存取远程服务

3、rmic产生stub、skeleton

  • JDK的rmic工具利用服务的实现产生stub和skeleton两个类

4、启动RMI registry。rmiregistry就像电话簿,用户从此取得代理(客户端的stub helper)

5、启动远程服务。实现服务的类实例化对象并向RMI registry注册,注册后才能对用户提供服务

code:

(创建远程服务后) 客户端如何取得stub对象:

  1. 客户端查询RMIregistry:Naming.lookup(“rmi://127.0.0.1/Remote Hello”);
  2. RMI registry返回解序列化的stub对象。(客户端必须要有由rmic产生的stub类,否则stub类不会在客户端解序列化)
  3. 客户端就像调用真正服务一样调用stub上的方法

 

Servlet——多多关注

servlet是放在HTTP Web服务器上运行的Java程序,用户通过浏览器与网页进行交互式,request会发送给网页服务器,若request需要servlet,服务器会执行或调用servlet,得到用户所请求的结果

创建并执行servlet

  1. 找出可以存放servlet的地方。方便服务器存取servlet文件。
  2. 取得servlets.jar并添加到classpath上。servlet不是Java标准库的一部分,需要servlets.jar文件中的servlet相关包才能编译出servlet
  3. 通过extend类HeepServlet来编写servlet类。servlet是个extend过HttpServlet的类
  4. 编写HTML调用servlet。当用户点击引用到servlet的网页链接时,服务器会找到servlet并根据HTTP的GET、POST等命令调用适当方法
  5. 给服务器设定HTML网页和servlet。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值