以下为个人学习笔记和习题整理
课程:面向对象程序设计 ——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

  • FileReaderInputStreamReader 类的子类,所有方法都从父类中继承而来。
    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
    InputStreamReader 上建立一个 Scanner 对象可以从流中的文本中解析出以文本表达的各种基本类型
    next...()

  • Stream / Reader / Scanner 选哪个

graph LR
A{数据是二进制的} -->|是| B[用InputStream]
A --> |否|C{表达的是文本}
C -->|是| D[用Reader] 
C -->|否| E[用Scanner]

# 阻塞 / 非阻塞

read() 函数是阻塞的,在读到所需的内容之前会停下来等。
使用 read() 的更 “高级” 的函数,如 nextInt()readLine() 都是这样的。
所以常用单独的线程来做 socket 读的等待,或使用 niochannel 选择机制。
对于 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();
		}
	}
}

# 抛出异常

函数加throws声明
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();
		}		
	}
}
阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Ruri Shimotsuki 微信支付

微信支付

Ruri Shimotsuki 支付宝

支付宝

Ruri Shimotsuki 贝宝

贝宝