第8周 异常处理与输入输出【面向对象程序设计——Java语言笔记总结】

第8周 异常处理与输入输出

  • 8.1 异常
    • 捕捉异常
    • 异常捕捉机制
    • 捕捉到的异常
  • 8.2 异常机制
    • 自己制作异常throw
    • 异常捕捉时的匹配
    • 异常遇到继承
  • 8.3 流
    • 输入输出流
    • 文件流
    • 流过滤器
  • 8.4 文本输入输出
    • 文本流
    • 汉字编码
    • 格式化输入输出
  • 8.5 流的应用
    • 应用
    • 对象串行化

8.1 异常

捕捉异常

import java.util.Scanner;

public class ArrayIndex {
	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){ 
		//try{}中内容,遇到错误为()时,执行以下内容
		//ArrayIndexOutOfBoundsException:索引超过设定值9
			System.out.println("Caught");
		}
	}
}

异常捕捉机制

		try {
			//可能产生异常的代码
		}catch(Type1 id1) {
			//处理Type1异常的代码
		}catch(Type2 id2) {
			//处理Type2异常的代码
		}

第8周 异常处理与输入输出【面向对象程序设计——Java语言笔记总结】_第1张图片

捕捉到的异常

public class ArrayIndex {
	public static void f() {
		int[] a =new int[10];
		a[10]=10;
	}
	public static void g() {
		f();
	}
	public static void k() {
		try {
			g();
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("k()");
			throw e;
		}
	}
	public static void main(String[] args) {		
		try {
			k();
			System.out.println("hello");
		}catch(ArrayIndexOutOfBoundsException e){
			System.out.println("Caught");
			System.out.println(e.getMessage());
			System.out.println(e);
			e.printStackTrace();
		}
	}
}

输出:

k()
Caught
10
java.lang.ArrayIndexOutOfBoundsException: 10
java.lang.ArrayIndexOutOfBoundsException: 10
	at test_8.ArrayIndex.f(ArrayIndex.java:6)
	at test_8.ArrayIndex.g(ArrayIndex.java:9)
	at test_8.ArrayIndex.k(ArrayIndex.java:13)
	at test_8.ArrayIndex.main(ArrayIndex.java:22)

8.2 异常机制

  • 异常机制最大的好处是清晰地分开了正常的业务逻辑代码和遇到情况时的处理代码。
    第8周 异常处理与输入输出【面向对象程序设计——Java语言笔记总结】_第2张图片
    第8周 异常处理与输入输出【面向对象程序设计——Java语言笔记总结】_第3张图片

自己制作异常throw

class OpenException extends Throwable{
}
class CloseException extends Throwable{	
}

public class ArrayIndex {
	public static int open() {
		return -1;   //如果文件打开失败返回-1
	}
	public static void readFile() throws OpenException,CloseException { //声明有可能抛出异常
		if(open()==-1) {
			throw new OpenException(); 
		}
	}	
	public static void main(String[] args)  {
		try {
			readFile();   //函数有可能抛出异常,需要用try/catch结构
		} catch (OpenException e) {
			e.printStackTrace();
		} catch (CloseException e) {
			e.printStackTrace();
		}
	}
}

异常捕捉时的匹配

  • 抛出子类异常会被捕捉父类异常的catch捕捉到。
catch(Exception e){  //捕捉任何异常,万能捕捉器
	e.printStackTrace();
	System.out.println("Anything");
}

异常遇到继承

  • 异常声明
    • 如果调用一个声明会抛出异常的函数,必须:
    • 把函数的调用放在try块中,设置catch来捕捉所有可能抛出的异常
    • 或者声明自己会抛出无法处理的异常
  • 当覆盖一个函数的时候,子类不能声明抛出比父类的版本更多的异常
  • 在子类的构造函数中,必须声明父类可能抛出的全部异常,也可以加自己的异常

8.3 流

输入输出流

  • 流是输入输出的方式
  • 流的基础类
    • InputStream
    • OutputStream
    • 字节流
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();
		}
	}
}

文件流

  • FileInputStream
  • FileOutputStream
  • 对文件作读写操作
  • 实际工程中较少使用
    • 更常用的是以在内存数据或通信数据上建立的流,如数据库的二进制数据读写或网络端口通信
    • 具体的文件读写往往有更专业的类,比如配置文件和日志文件
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Main{ 
	
	public static void main(String[] args) {
		System.out.println("Hello World");
		byte[] buffer = new byte[10];
		for(int i=0;i<buffer.length;i++)
			buffer[i]=(byte)i;
		FileOutputStream out;
		try {
			out = new FileOutputStream("a.dat");
			out.write(buffer);
			out.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
}

流过滤器

  • 前面的流只能读取byte,如果想要读取int,可以加过滤器:
DataOutputStream out =new DataOutputStream(
						new BufferedOutputStream(
							new FileOutputStream("a.dat")));
int i = 112233;
out.writeInt(i);
out.close();

DataInputStream in = new DataInputStream(
			new BufferedInputStream(
				new FileInputStream("a.dat")));
int j = in.readInt();
System.out.println(j);
  • a.dat 二进制文件
  • 十进制显示

8.4 文本输入输出

文本流

PrintWriter out = new PrintWriter(
			new BufferedWriter(
				new OutputStreamWriter(
						new FileOutputStream("a.txt"))));
int i = 112233;
out.println(i);
out.close();

BufferedReader in = new BufferedReader(
					new InputStreamReader(
							new FileInputStream("a.txt")));
String line;
while((line=in.readLine())!=null) {
	System.out.println(line);
	// in.readLine() 返回一整行String,如果读到末尾返回Null
}
  • getLineNumber() 可以得到行号
  • FileReader

汉字编码

  • GB & uft-8
  • new InputStreamReader(new FileInputStream("a.txt"),"utf8")

格式化输入输出

  • PrintWriter
    • format(“格式”,…);
    • printf(“格式”,…);
    • print();
    • println();
  • Scanner
    • next…()
  • Stream/Reader/Scanner
    第8周 异常处理与输入输出【面向对象程序设计——Java语言笔记总结】_第4张图片

8.5 流的应用

应用

  • 建立socket网络连接,对服务器进行文本读写
public class Main{ 
	
	public static void main(String[] args) {
		try {
			Socket socket = new Socket(InetAddress.getByName("localhost"),12345);
			PrintWriter out = new PrintWriter(
					new BufferedWriter(
							new OutputStreamWriter(
									socket.getOutputStream())));  // 得到虚拟的流,我与服务器之间的网络连接,构建了一个writer,可以送东西过去
			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 (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
  • 使用nc在12345端口监听:nc -l -p 12345
  • 阻塞/非阻塞
    • read()函数是阻塞的,在读到所需内容之前会停下来等待
    • 使用read()的更“高级”的函数,如nextInt(),readLine()都是这样的
    • 所以常用单独的线程来做socket读的等待,或使用nio的channel选择机制
    • 对于socket,可以设置SO时间setSoTimeout(int timeOut)

对象串行化

  • ObjectInputStream类
    • readObject()
  • ObjectOutputStream类
    • writeObject()
  • Serializable接口
  • 类的对象写到文件里,可以读出来
class Student implements Serializable{ //可串行化的类
	private String name;
	private int age;
	private int grade;
	public Student(String name,int age,int grade) {
		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( //将s1写入文件里
					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();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
}

你可能感兴趣的:(Java)