以下为个人学习笔记和习题整理
课程:面向对象程序设计 ——Java 语言
- 浙江大学 - 翁恺 @ 中国大学 MOOC
https://www.icourse163.org/course/ZJU-1001542001
# 课堂笔记
# 异常
# 捕捉异常 try
catch
try { | |
// 可能产生异常的代码 | |
} catch(Type1 id1) { | |
// 处理 Type1 异常的代码 | |
} catch(Type2 id2) { | |
// 处理 Type2 异常的代码 | |
} catch(Type3 id3) { | |
// 处理 Type3 异常的代码 | |
} |
拿到异常对象之后,可以:
String getMessage(); | |
String toString(); | |
void printStackTrace(); |
或再度抛出 throw
:
catch(Exception e) { | |
System.err.println("An exception was thrown"); | |
throw e; | |
} |
捕捉任何异常:
catch(Exception e) { | |
System.err.println("Caught an exception"); | |
} |
像 ArrayIndexOutOfBoundsException
运行时刻异常,这样的异常是不需要声明的,但是如果没有适当的机制来捕捉,就会最终导致程序终止。
# 抛出异常 throw
- 如果函数可能抛出异常,必须在函数头部加以
throws
声明
void f() throws TooBig, TooSmall, DivZero { } |
可以声明并不会真的抛出的异常。
- 任何继承了
Throwable
类的对象才可以throw
扔出。Exception
类继承了Throwable
throw new Exception(); | |
throw new Exception("HELP"); |
# 异常声明和继承
调用一个声明会抛出异常的函数,必须把函数的调用放在 try
块中,并设置 catch
来捕捉所有可能抛出的异常;或声明自己会抛出无法处理的异常。
当覆盖一个函数的时候,子类不能声明抛出比父类的版本更多的异常。
在子类的构造函数中,必须声明父类可能抛出的全部异常。
# 流
流是输入输出的方式
流是一维单向的
# 流的基础类 InputStream
OutputStream
InputStream
类包含的方法read()
读字节int read()
读到最后返回-1
read(byte b[])
read(byte[], int off, int len)
skip(long n)
int available()
流里面还有多少字节可读mark()
标记reset()
回到前面标记的地方boolean markSupported()
是否支持标记close()
OutStream
类包含的方法write()
write(int b)
输出单个字节write(byte b[])
输出一个字节数组write(byte b[], int off, int len)
flush()
close()
# 文件流 FileInputStream
FileOutputSream
对文件作读写操作
实际工程中已经较少使用。
更常用的是以在内存数据或通信数据上建立的流,如数据库的二进制数据读写,或网络端口通信。
具体的文件读写往往有更专业的类,比如配置文件和日志文件。
# 流过滤器 DataInputStream
DataOutputStream
以一个介质流对象为基础,层层构建过滤器流,最终形成的流对象能在数据的输入输出过程中,逐层使用过滤器流的方法来读写数据。
用以读写二进制方式表达的基本数据类型的数据
# 文本流 Reader
Writer
二进制数据采用
InputStream
OutputStream
文本数据采用Reader
Writer
处理Unicode
字符
PrintWriter pw= new PrintWriter( | |
new BufferedWriter( | |
new OutputStreamWriter( | |
new FileOutputStream("abc.txt")))); |
# 文件读取
常用的是
BufferedReader
类及其readLine()
方法。此外还有
LineNumberReader
类可以得到行号,getLineNumber
。FileReader
是InputStreamReader
类的子类,所有方法都从父类中继承而来。FileReader(File file)
在给定从中读取数据的File
的情况下创建一个新FileReader
。FileReader(String fileName)
在给定从中读取数据的文件名的情况下创建一个新FileReader
。FileReader
不能指定编码转换方式。
# 汉字编码
BufferedReader in = new BufferedReader( | |
new InputStreamReader( | |
new FileInputStream("utf8.txt"), "utf8")); |
InputStreamReader(InputStream in)
创建一个使用默认字符集的InputStreamReader
InputStreamReader(InputStream in, Charset cs)
创建使用给定字符集的InputStreamReader
InputStreamReader(InputStream in, CharsetDecoder dec)
创建使用给定字符集解码器的InputStreamReader
InputStreamReader(InputStream in, String charsetName)
创建使用指定字符集的InputStreamReader
# 格式化输入输出
输出
PrintWriter
类的方法有:format("格式", ...)
printf("格式", ...)
print(各种基本类型)
println(各种基本类型)
输入
Scanner
类
在InputStream
或Reader
上建立一个Scanner
对象可以从流中的文本中解析出以文本表达的各种基本类型next...()
Stream
/Reader
/Scanner
选哪个
graph LR | |
A{数据是二进制的} -->|是| B[用InputStream] | |
A --> |否|C{表达的是文本} | |
C -->|是| D[用Reader] | |
C -->|否| E[用Scanner] |
# 阻塞 / 非阻塞
read()
函数是阻塞的,在读到所需的内容之前会停下来等。
使用 read()
的更 “高级” 的函数,如 nextInt()
、 readLine()
都是这样的。
所以常用单独的线程来做 socket
读的等待,或使用 nio
的 channel
选择机制。
对于 socket
,可以设置 SO 时间
setSoTimeout(int timeOut) |
# 对象串行化
ObjectInputStream
类readObject()
ObjectOutputStream
类writeObject()
Serializable
接口
# 课内代码
# 异常捕捉
package exception | |
import java.util.Scanner; | |
public class ArrayIndex { | |
public static void f() { | |
int[] a = new int[10]; | |
a[10] = 10; | |
System.out.prinln("hello"); | |
} | |
public static void g() { | |
f(); | |
} | |
public static void h() { | |
int i = 10; | |
if (i < 100) { | |
g(); | |
} | |
} | |
public static void k() { | |
try { | |
h(); | |
} catch(ArrayIndexOutOfBoundsException e) { | |
System.out.println("k()"); | |
throw e; // 再度抛出 | |
} | |
} | |
public static void main(String[] args) { | |
// int[] a = new int[10]; | |
// int idx; | |
// Scanner in = new Scanner(System.in); | |
// idx = in.nextInt(); | |
// try { | |
// a[idx] = 10; | |
// System.out.println("hello"); | |
// } catch (ArrayIndexOutOfBoundsException e) { | |
// System.out.println("Cought"); | |
// } | |
// | |
// try { | |
// f(); | |
// } catch (ArrayIndexOutOfBoundsException e) { | |
// System.out.println("Cought"); | |
// } | |
try { | |
k(); | |
} catch (ArrayIndexOutOfBoundsException e) { | |
System.out.println("Caught"); | |
System.out.println(e.getMessage()); | |
System.out.println(e); // 相当于 System.out.println (e.toString ()) | |
e.printStackTrace(); | |
} | |
} | |
} |
# 抛出异常
package exception | |
class OpenException extends Throwable {} | |
class CloseException extends Throwable {} | |
public class ArrayIndex { | |
public static int open() { | |
return -1; | |
} | |
public static void readFile() throws OpenException, CloseException { | |
if (open() == -1) { | |
throw new OpenException(); | |
} | |
} | |
public static void main(String[] args) { | |
try { | |
readFile(); | |
} catch (OpenException e) { | |
} catch (CloseException e) { | |
} | |
} | |
} |
package exception | |
class OpenException extends Exception {} | |
class CloseException extends OpenException {} | |
public class ArrayIndex { | |
public static int open() { | |
int[] a = new int[10]; | |
a[10] = 10; | |
return -1; | |
} | |
public static void readFile() throws OpenException, CloseException { | |
if (open() == -1) { | |
throw new OpenException(); | |
} | |
} | |
public static void main(String[] args) { | |
try { | |
readFile(); | |
} catch (NullPointerException e) { | |
System.out.println("Null"); | |
} catch (OpenException e) { | |
System.out.println("Open"); | |
} catch (Exception e) { // 捕捉任何异常 | |
System.out.println("Anything"); | |
} | |
} | |
} |
package exception | |
class OpenException extends Exception {} | |
class CloseException extends OpenException {} | |
class NewException extends Exception {} | |
public class ArrayIndex { | |
public ArrayIndex() throws OpenException {} // 构造函数抛出异常 | |
public void f() throws OpenException {} | |
public static void main(String[] args) { | |
} | |
} | |
class NewClass extends ArrayIndex { | |
public NewClass() {} // 错误 | |
public NewClass() throws OpenException, NewException {} // 正确,必须加上 throws 声明父类所有可能会抛出的异常,可以加上其他自己的异常 | |
public void f() {} // 正确 | |
public void f() throws NewException {} // 错误,不可以加父类方法未声明的异常 | |
public void f() throws CloseException {} // 正确 | |
public static void main(String[] args) { | |
try { | |
ArrayIndex p =new NewClass(); | |
p.f(); | |
} catch(OpenException e) { | |
} catch(NewException e) { | |
} | |
} | |
} |
# 流
package hello; | |
import java.io.IOException; | |
public class Main { | |
public static void main(String[] args) { | |
System.out.println("hello world"); | |
byte[] buffer = new byte[1024]; | |
try { | |
int len = System.in.read(buffer); | |
String s = new String(buffer, 0, len); | |
System.out.println("读到了"+len+"字节"); | |
System.out.println(s); | |
System.out.println("s的长度是:"+s.length()); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |
package hello; | |
import java.io.FileNotFoundException; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
public class Main { | |
public static void main(String[] args) { | |
byte[] buf = new byte[10]; | |
for( int i=0; i < buf.length; i++) { | |
buf[1] = (byte) i; | |
} | |
try { | |
FileOutputStream out = new FileOutputStream("a.dat"); | |
out.write(buf); | |
out.close(); | |
} catch (FileNotFoundException e) { | |
e.printStackTrace(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |
package hello; | |
import java.io.BufferedInputStream; | |
import java.io.BufferedOutputStream; | |
import java.io.DataInputStream; | |
import java.io.DataOutputStream; | |
import java.io.FileInputStream; | |
import java.io.FileNotFoundException; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
public class Main { | |
public static void main(String[] args) { | |
byte[] buf = new byte[10]; | |
for( int i=0; i < buf.length; i++) { | |
buf[1] = (byte) i; | |
} | |
try { | |
DataOutputStream out = new DataOutputStream( | |
new BufferedOutputStream( | |
new FileOutputStream("a.dat"))); | |
// int i = 0xcafebabe; | |
int i = 123456; | |
out.writeInt(i); | |
out.close(); | |
DataInputStream in = new DataInputStream( | |
new BufferedInputStream( | |
new FileInputStream("a.dat"))); | |
int j = in.readInt(); | |
System.out.println(j); | |
} catch (FileNotFoundException e) { | |
e.printStackTrace(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |
package hello; | |
import java.io.BufferedReader; | |
import java.io.BufferedWriter; | |
import java.io.FileInputStream; | |
import java.io.FileNotFoundException; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
import java.io.OutputStreamWriter; | |
import java.io.PrintWriter; | |
public class Main { | |
public static void main(String[] args) { | |
byte[] buf = new byte[10]; | |
for( int i=0; i < buf.length; i++) { | |
buf[1] = (byte) i; | |
} | |
try { | |
PrintWriter out= new PrintWriter( | |
new BufferedWriter( | |
new OutputStreamWriter( | |
new FileOutputStream("a.txt")))); | |
int i = 123456; | |
out.println(i); | |
out.close(); | |
BufferedReader in = new BufferedReader( | |
new InputStreamReader( | |
new FileInputStream("src/hello/Main.java"))); | |
String line; | |
while((line = in.readLine()) != null) { | |
System.out.println(line); | |
} | |
} catch (FileNotFoundException e) { | |
e.printStackTrace(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |
package hello; | |
import java.io.BufferedReader; | |
import java.io.BufferedWriter; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
import java.io.OutputStreamWriter; | |
import java.io.PrintWriter; | |
import java.net.InetAddress; | |
import java.net.Socket; | |
public class Main { | |
public static void main(String[] args) { | |
try { | |
// 建一个 Socket 链接到本地的 12345 端口 | |
Socket socket = new Socket(InetAddress.getByName("localhost"), 12345); | |
PrintWriter out = new PrintWriter( | |
new BufferedWriter( | |
new OutputStreamWriter( | |
socket.getOutputStream()))); | |
out.println("Hello"); | |
out.flush(); // 刷新缓存 | |
BufferedReader in = new BufferedReader( | |
new InputStreamReader( | |
socket.getInputStream())); | |
String line; | |
line = in.readLine(); | |
System.out.println(line); | |
out.close(); | |
socket.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |
package hello; | |
import java.io.FileInputStream; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
import java.io.ObjectInputStream; | |
import java.io.ObjectOutputStream; | |
class Student { | |
private String name; | |
private int age; | |
private int grade; | |
public Student(String name, int age, int grade) { | |
super(); | |
this.name = name; | |
this.age = age; | |
this.grade = grade; | |
} | |
public String toString() { | |
return name + " " + age + " " + grade; | |
} | |
} | |
public class Main { | |
public static void main(String[] args) { | |
try { | |
Student s1 = new Student("John", 18, 5); | |
System.out.println(s1); | |
ObjectOutputStream out = new ObjectOutputStream( | |
new FileOutputStream("obj.dat")); | |
out.writeObject(s1); | |
out.close(); | |
ObjectInputStream in = new ObjectInputStream( | |
new FileInputStream("obj.dat")); | |
Student s2 = (Student)in.readObject(); | |
System.out.println(s2); | |
in.close(); | |
System.out.println(s1 == s2); | |
//false 虽然内容一样,但不是相同的对象 | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} catch (ClassNotFoundException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |