Java进阶学习笔记终篇

1、异常:

1.1 捕捉异常:数组下标越界

image.png

解决异常:用try{ }catch( ){ }处理;
image.png

1.2 异常捕捉机制:

捕捉异常:

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

异常发生并不意味着程序一定要终止

package exception;

import java.util.Scanner;

public class ArrayIndex {

    public static void f() {
        int[] a = new int[10];
        a[10] = 10;
        System.out.println("hello");
    }
    
    public static void main(String[] args) {
        try {
            f();
        }catch(ArrayIndexOutOfBoundsException e) {
            System.out.println("caught");
        }
        System.out.println("main");
    }
}
image.png

image.png
package exception;

import java.util.Scanner;

public class ArrayIndex {

    public static void f() {
        int[] a = new int[10];
        a[10] = 10;//抛出异常
        System.out.println("hello");
    }
    
    public static void g() {
        f();
    }
    
    public static void h() {
        int i=10;
        if(i<100) {
            g();//不是函数
        }
    }
    
    public static void k() {
        try {
            h();
        }catch(NullPointerException e) {
            System.out.println("k()");
        }
    }
    
    public static void main(String[] args) {
        try {
            k();
        }catch(ArrayIndexOutOfBoundsException e) {
            System.out.println("caught");
        }
        System.out.println("main");
    }   
}

1.3 捕捉到的异常:

  • 捉到了做什么?
    • String getMessage();
    • String toString();
    • void printStackTrace();
    • 但是肯定是回不去了,而具体的处理逻辑则取决于你的业务逻辑需要;
    • 调用轨迹:


      image.png
  • 再度抛出:
  catch(Exception e){
         System.err.println("An exception was thrown");
          throw e;
}

如果在这个层面上需要处理,但是不能做最终的决定

1.4 异常:

  • 如果要读文件:打开文件--判断文件大小--分配足够的内存空间--把文件读入内存--关闭文件;(遇到异常很难处理、时间依赖性较大、缺乏提前预警处理)
    用上异常机制(Business Logic)
try{
  open the file;
  determine its size;
  allocate that much memory;
  read the file into memory;
  close the file;
}catch(fileOpenFailed){
  doSomething;
}catch(sizeDeterminatedFailed){
  doSomething;
}catch(memoryAllocationFailed){
  doSomething;
}catch(readFailed){
  doSomething;
}catch(fileCloseFailed){
  doSomething;
}
  • 异常:(异常机制最大的好处就是清晰地分开了正常的业务逻辑代码和遇到情况时的处理代码
    • 有不寻常的事情发生了;
    • 当这个事情发生的时候,原本打算要接着做的事情不能再继续了,必须得要停下来,让其他地方的某段代码来处理;

1.5 异常的抛出与声明:

  • 异常声明:
    • 如果你的函数可能抛出异常,就必须在函数头部加以声明;
void f() throws TooBig,TooSmall,DivZero{//....
void f(){..}
  • 你可以声明并不会真的抛出的异常;
  • 什么能扔?
    • 任何继承了Throwable类的对象;
    • Exception类继承了Throwable;
    • throw new Exception();
    • throw new Exception("HELP");
package exception;

class OpenException extends Throwable{
    
}
class CloseException extends Throwable{
    
}
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) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (OpenException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (CloseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }   
}

1.6 异常捕捉时的匹配:

  • catch怎么匹配异常的?
    • Is-A的关系;
    • 就是说,抛出子类异常会被捕捉父类异常的catch给捉到;
  • 捕捉任何异常:
 catch(Exception e){
 System.err.println("Caught an exception");
}
  • 运行时刻异常:
    • 像ArraylndexOutOfBoundsException这样的异常是不需要声明的;
    • 但是如果没有适当的机制来捕捉,就会最终导致程序终止;
  • 异常声明:
    • 如果你调用一个声明会抛出异常的函数,那么你必须;
      • 把函数的调用放在try块中,并设置catch来捕捉所有可能抛出的异常;
      • 或声明自己会抛出无法处理的异常;
  • 异常声明遇到继承关系:
    • 当覆盖一个函数的时候,子类不能声明抛出比父类的版本更多的异常;
    • 在子类的构造函数中,必须声明父类可能抛出的全部异常;
    • 成员函数不能增加更多的异常,构造函数可以;
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() throws OpenException,NewException {}//构造函数
    public void f() {}
    public static void main(String[]args) {
        try {
            ArrayIndex p = new NewClass();//向上造型
            p.f();
        } catch (OpenException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NewException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

2、流:(stream)

2.1 流是输入输出的方式

  • 流是一维单向的;
  • 流的基础类:
    • InputStream:(当做字节流来看待)
      • read():int read()表示读到头了,返回-1;read(byte b[]);read(byte[],int off,int len):读字节;
      • skip(long n);
      • int available();表示流里面现在还有多少字节供你读
      • mark();读到流的某个地方做标记,继续往前读
      • reset();读到某个地方重新回到之前的某个地方
      • boolean markSupported();
      • close();
    • OutputStream:
      • write():write(int b); write(byte b[]); write(byte b[],int off,int len);
      • flush();
      • close();
    • http://docs.oracle.com/javase/8/docs/api/overviewsummary.html
      image.png
package hello;

import java.io.IOException;
import java.util.Scanner; 
public class main {
    public static void main(String[] args) {
        System.out.println("hello world");//out就是某种用来做输出的流;
        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) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

image.png

注意字节和字符的区别

2.2 文件流:

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

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner; 
public class main {
    public static void main(String[] args) {
        System.out.println("hello world");//out就是某种用来做输出的流;
        byte[] buf = new byte[10];
        for(int i=0;i<buf.length;i++) {
            buf[i] = (byte)i;
        }
        try {
            FileOutputStream out = new FileOutputStream("a.dat");
            out.write(buf);
            out.close();
        }catch(FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
image.png

2.3 流过滤器:

  • 以一个介质流对象为基础层层构建过滤器流,最终形成的流对象能在数据的输入输出过程中,逐层使用过滤器的方法来读写数据;
package hello;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner; 
public class main {
    public static void main(String[] args) {
        System.out.println("hello world");//out就是某种用来做输出的流;
        byte[] buf = new byte[10];
        for(int i=0;i<buf.length;i++) {
            buf[i] = (byte)i;
        }
        try {
            DataOutputStream out = new DataOutputStream(
                    new BufferedOutputStream(
                    new FileOutputStream("a.dat")));//写字节,套过滤器
            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) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
  • Data:
    • DataInputStream;
    • DataOutputStream;
    • 用以读写而金子方式表达的基本数据类型的数据;

3、文本输入输出:

3.1 文本流:

  • Reader/Writer:
    • 二进制数据采用InputStream/OutputStream;
    • 文本数据采用Reader/Writer;
  • 在流上建立文本处理:
PrintWriter pw = new PrintWriter(
  new BufferedWriter(
    new OutputStreamWriter(
      new FileOutputStream("abc.txt")));
try {
            PrintWriter out = new PrintWriter(
                    new BufferedWriter(
                            new OutputStreamWriter(
                                    new FileOutputStream("a.txt"))));//写字节,套过滤器
            int i=123456;//十进制,到文件自动变成八进制;
            out.println(i);
image.png
  • Reader:
    • 常用的是BufferedReader;
    • readLine();
BufferedReader in = new BufferedReader(
                    new InputStreamReader(
                            new FileInputStream("src/hello/Main.java")));
            String line;
            while((line=in.readLine())!=null){
                System.out.println(line);
            }
image.png
  • LineNumberReader:
    • 可以得到行号;
      • getLineNumber();
  • FileReader:
    • InputStreamReader类的子类,所有方法都从父类中继承而来;
    • FileReader(File file):
      • 在给定从中读取数据的File的情况下创建一个新FileReader;
    • FileReader(String fileName):
      • 在给定从中读取数据的文件名的情况下创建一个新FileReader;
    • FileReader不能指定编码转换方式;

3.2 汉字编码:

  • InputStreamReader(InputStream in) 创建一个使用默认字符集的InputStreamReader。
  • InputStreamReader(InputStream in,Charset cs) 创建使用给定字符集的 InputStreamReader。
  • InputStreamReader( InputStream in,CharsetDecoder dec) 创建使用给定字符集解码器的 InputStreamReader。
  • InputStreamReader( InputStream in,String charsetName) 创建使用给定字符集的 InputStreamReader。

3.3 格式化输入输出:

  • PrintWriter:
    • format("格式",...);
    • printf("格式",...);
    • print(各种基本类型);不带回车
    • println(各种基本类型);带回车
  • Scanner:
    • 在InputStream或Reader上建立一个Scanner对象可以从流中的文本中解析出以文本表达的各种基本类型;
    • next...();


      image.png

3.4 流的应用:

  • 阻塞/非阻塞:
    • read()函数时阻塞的,在读到所需的内容之前会停下来等;
    • 使用read()的更“高级”的函数,如nextInt()、readLine()都是这样的;
    • 所示常用单独的线程来做socket读的等待,或使用nio的channel选择机制;
    • 对于socket,可以设置SO时间:
      • setSoTimeout(int timeOut);
package main;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.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())));
            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();
        }
    }     
}

3.5 对象串行化:

  • ObjectInputStream类:
    • readObject;
  • ObjectOutputStream类:
    • writeObject();
  • Serializable接口:
package main;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.Socket;

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(
                    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);
        }catch(IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }      
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,552评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,666评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,519评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,180评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,205评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,344评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,781评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,449评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,635评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,467评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,515评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,217评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,775评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,851评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,084评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,637评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,204评论 2 341

推荐阅读更多精彩内容

  • 一、基础知识:1、JVM、JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机...
    杀小贼阅读 2,361评论 0 4
  • Java 语言支持的类型分为两类:基本类型和引用类型。整型(byte 1, short 2, int 4, lon...
    xiaogmail阅读 1,342评论 0 10
  • 小编费力收集:给你想要的面试集合 1.C++或Java中的异常处理机制的简单原理和应用。 当JAVA程序违反了JA...
    八爷君阅读 4,564评论 1 114
  • JAVA面试题 1、作用域public,private,protected,以及不写时的区别答:区别如下:作用域 ...
    JA尐白阅读 1,142评论 1 0
  • 李丹丹焦点网络初期13期,坚持分享第99天。 刚开始上课刘老师让写分享的时候,感觉让每天坚持写分享,真得...
    随其自然1阅读 94评论 0 0