异常处理
如何判断一个方法中可能抛出异常
- 该方法中出现throw语句
- 该方法调用了其他已经带throws子句的方法。
如果方法中可能抛出异常,有两种处理方法:
1.若当前方法有能力处理异常,则用Try-catch
public void A(int x) { try{ if (x == 0) throw new Exception("Zero"); } catch(Exception e) { //do sth } }
2.若当前方法没有能力处理异常,则在方法的声明处写上throws语句。
public void A(int x) throws Exception { if (x == 0) throw new Exception("Zero"); }
finally:总是会被执行的语句。
不管try代码块中是否出现异常,finally代码块总是被执行。
(1)finally唯一不被执行的情况就是先执行了System.exit();
public static void main(String[] args) { try { System.out.println("Begin"); System.exit(0); } finally { System.out.println("Finally"); } System.out.println("End"); }
结果为Begin
public static void main(String[] args) throws Exception { try { System.out.println("Begin"); A(0); //抛出异常 System.exit(0); } catch(Exception e) { System.out.println("Wrong"); throw e; } finally { System.out.println("Finally"); } System.out.println("End"); }
输出结果为
Begin
Wrong
Finally
因为main方法已经抛出了异常,所以异常终止,不会继续执行下去。
假如注释掉throw e;这条语句
public static void main(String[] args) throws Exception { try { System.out.println("Begin"); A(0); //抛出异常 System.exit(0); } catch(Exception e) { System.out.println("Wrong"); //throw e; } finally { System.out.println("Finally"); } System.out.println("End"); }
输出结果为
Begin
Wrong
Finally
End
(2)假如含有return语句,那么finally会在return之前执行。
public void A(int x) throws Exception { if (x == 0) throw new Exception("Zero"); //3 } piblic int B(int x) { try { System.out.println("Begin"); //1 A(x); //2 return 1; } catch(Exception e) { System.out.println(e.getMessage()); //4 return 0; //6 } finally { System.out.println("Finally"); //5 } } public static void main(String[] args) { System.out.println(B(0)); //7 }
输出结果为
Begin
Zero
Finally
0
throw与throws
注意throw与throws的区别:
throw是方法中抛出异常时使用的句子。
throws是方法名称后面用于声明该方法可能抛出的异常的句子。
异常处理的语法规则
- try不能单独存在,后面至少要接一个catch或finally
- try后面可以有0个或多个catch,可以有0个或1个finally,但不能2种都是0个。
- try后面若有多个catch,则出现异常时会根据顺序去匹配catch,所以小类异常的catch应当放在更前一些。
数组
数组的声明与c++有所不同
int[] s; (√)
int s[]; (√)
int s[30]; (×)
int[] s = new int[30]; (√)
int[] s = new int[]{1,2,3}; (√)
int[] s = new int[3]{1,2,3}; (×)
Java中数组的长度可以用s.length来获取。
线程初步
线程的创建和启动有2种方法:
1.继承Thread类
public class S extends Thread { public void run() { //do sth; } } S s = new S(); s.start(); //start()会自动调用run()
2.实现Runnable接口
public class S implements Runnable { public void run() { } } S s = new S(); Thread thread = new Thread(s); thread.start();
尽管S实现了run方法,但S始终不是线程类,所以要重新创建一个线程类。
Thread中有这样的构造方法
Thread(Runnable runnable);
输入/输出
InputStream,OutputStream类 字节输入/输出流(最小的传输数据是字节)
Reader,Writer类 字符输入/输出流(最小的传输数据是字符)
字节输入流
所有的字节输入流都是InputStream类的子类。
文件输入流是InputStream的子类:
FileInputStream(File file);
FileInputStream(String name);
过滤输入流FilterInputStream(可以按照需要来读取相应的数据类型,如double,int)
FilterInputStream有以下2个子类:
BufferedInputStream 利用缓冲区来提高读写效率
DataInputStream 与DataOutputStream配合,可以从流中读取基本类型(int,double,char等)数据。
BufferedInputStream:
BufferedInputStream(InputStream in) //装饰输入流In
BufferedInputStream(InputStream in, int size) //装饰输入流in,指定缓冲区大小
FileOutputStream out1 = new FileOutputStream("C:\test.txt"); //装饰文件输出流 BufferedOutputStream out2 = new BufferedOutputStream(out1); //装饰带缓冲的文件输出流 DataOutputStream out3 = new DataOutputStream(out2); out3.writeByte(-12); out3.flush(); //无论缓冲区是否满,都输出 out3.writeDouble(1.2); out3.writeChar('a'); out3.close(); //close()会自动调用flush() InputStream in1 = new InputStream("C:\test.txt"); //装饰文件输入流 BufferedInputStream in2 = new BufferedInputStream(in1); //装饰带缓冲的文件输入流 DataOutputStream in3 = new DataOutputStream(in2); int a = in3.readByte(); double b = in3.readDouble(); char c = in3.readChar(); in3.close(0);
字节输出流同理
Reader类
Reader类有以下子类
InputStreamReader
FileReader
BufferedReader
InputStreamReader
InputStreamReader(InputStream in) //按默认编码方式读取输入流中的字符
InputStreamReader(InputStream in, String charsetName) //按给定编码方式读取输入流中的字符
FileReader(File file)
FileReader(String name)
BufferedReader
BufferedReader(Reader in)
BufferedReader(Reader in, int size)
InputStream in1 = new FileInputStream("C:\test.txt"); InputStreamReader in2 = new InputStreamReader(in1, "UTF-8"); BufferedReader in3 = new BufferedReader(in2); StringWriter buffWriter = new StringWriter(); int data; while ((data = in3.read()) != -1) buffWriter.write(data); in3.close; String result = buffWriter.toString();
若有编码的问题,则应当考虑使用Reader/Writer而不是InpuStream/OutputStream.