异常

语法定义:

try {
    可能出现异常的代码片段
}catch(XXXException e){
        捕获try中出现的XXXException后的处理操作代码
}
    System.out.println("程序开始了");
    try {
        String string = "";
        System.out.println(string.length());
        System.out.println(string.charAt(0));
        /*
         * 在try中出错语句以下的代码都不会被执行
         */
        System.out.println("dfd");
    } catch (NullPointerException e) {
        System.out.println("出现了空指针");
    } catch (StringIndexOutOfBoundsException e) {
        System.out.println("字符串下标索引越界");
        /*
         * 应当有一个好习惯,在最后一个catch处捕获exception,防止未捕获的异常导致程序中断
         */
    } catch (Exception e){
        System.out.println("未知异常发生");
    }
    System.out.println("程序结束了");


finally块

finally块时定义在异常处理机制的最后一块.它可以直接跟在try之后或者最后一个catch之后.
finally可以保证只要程序执行到了try块当中,那么无论try块中的语句是否会抛出异常,finally都确保其内哦那个一定被执行.
* 通常会释放资源等操作放在finally中,如流的关闭操作.

try {
    String string = "";
    System.out.println(string.length());
    return ;
} catch (Exception e) {
    System.out.println("程序出错了");
}finally {
    System.out.println("finally块执行了");
}
标准流关闭
try {
    fos = new FileOutputStream("./demo./sf.dat");
    fos.write(1);
} catch (Exception e) {
    e.printStackTrace();
} finally {
    try {
        if(fos != null)
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

* JDK7后推出了一个新特性
 * java 中实现了AotuClose接口的类,都可以被改特性自动关闭
 try (FileOutputStream fos = new FileOutputStream("./demo/fos.dat");) {
     fos.write(1);
 } catch (Exception e) {
     e.printStackTrace();
 }

finally常见面试题

请说明:final,finally,finalize
finalize是Object定义的方法,该方法是被GC执行的额方法,当一个对象即将被GC释放前,GC会调用该方法.
调用该方法完意味着该对象即将被释放.
final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。内部类要访问局部变量,局部变量必须定义成final类型。
finally是异常处理语句结构的一部分,表示总是执行。

/*
  *System.out.println(test("0") + "," + test(null) + "," + test(""));//3,3,3
  */ 
 public static int test(String str) {
     try {
         return str.charAt(0) - '0';
     } catch (NullPointerException e) {
         return 1;
     } catch (Exception e) {
         return 2;
     } finally {
         return 3;//返回值覆盖
     }
 }
 throw (new ...)& throws
 Person:
 /*
 * 当一个方法使用throws声明一个异常的抛出时,那么调用这在调用该方法时就必须处理这个异常
 */
 public void setAge(int age) throws Exception {
     if(age > 100 || age < 0) 
         /*
          * 当一个方法当中使用throw抛出什么异常,就要在方法上使用throws声明该异常的抛出,
          * 只有RuntimeException无需这样,其他类型异常则是必须的,否则编译不通过
          */
         throw new Exception("年龄不合法");
     this.age = age;



ThrowDemo:

/*
 * 通常一个方法抛出异常有两种情况throw
 * 1:方法当中遇到了满足语法要求,但是不满足业务逻辑需要
 * 2;方法中确实出现了异常,但是该异常不应该由该方法处理,会抛出给调用者解决
 */
try {
    /*
     * 当调用一个含有throws声明异常抛出的方法时,编译器提示必须处理该异常,处理的手段有
     * 两种:
     * 1:使用try...catch捕获并处理该异常
     * 2:继续在当前方法上使用throws声明并抛出异常
     */
    p.setAge(1000);
} catch (Exception e) {
    System.out.println("出错了");
}

子类重写父类含有throws声明异常抛出的方式和对throws的重写规则
重写的规则====>两同,两小,一大

public class ThrowsDemo {
public void dosome() throws IOException ,AWTException{}
}

class Son extends ThrowsDemo {

//  public void dosome() throws IOException, AWTException {} 抛出相同的异常√

//  public void dosome(){}  不抛出异常√

//  public void dosome() throws IOException{}  抛出父类的部分异常√

//  public void dosome() throws FileNotFoundException {}   抛出父类的异常的子类异常√

//  public void dosome() throws SQLException{}   不可以抛出额外异常×

//  public void dosome() throws Exception{}    不可以抛出比父类异常还大的异常×

}

e.printStackTrace();用于输出错误信息,有助于找到并解决错误

自定义异常

通常用来说明我们程序中的某个业务逻辑错误 因为java提供的 异常基本上没有描述实际项目中的业务错误, 这时我们可以自定义一个异常.

public class IllegalAgeException extends Exception {//:定义异常名称,见名知意
private static final long serialVersionUID = 1L;//添加版本号
/*添加构造方法*/
public IllegalAgeException() {
    super();
}

public IllegalAgeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
    super(message, cause, enableSuppression, writableStackTrace);
}

public IllegalAgeException(String message, Throwable cause) {
    super(message, cause);
}

public IllegalAgeException(String message) {
    super(message);
}

public IllegalAgeException(Throwable cause) {
    super(cause);
}


网络编程

套接字Socket:

封装了TCP协议的通讯细节,让我们可以简单的使用它完成TCP通讯.
Socket链接后提供了两条流,通过两条流的读写操作完成与远端计算机的数据交换.
ServerSocket
 运行在服务端的ServerSocket主要有两个作用:
 1:向系统申请服务端口,客户端就是通过这个端口与服务端建立连接的.
 2:监听服务端口,一旦客户端与服务端建立连接,就会自动创建一个Socket,并通过该
 Socket与建立连接的客户端进行交互
客户端:

public class Client {
    /*
     * Socket套接字 
     * 封装了TCP协议的通讯细节,让我们可以简单的使用它完成TCP通讯 Socket链接
     * 后提供了两条流,通过两条流的读写操作完成与远端计算机的数据交换.
     */
    private Socket socket;

    /*
     * 用来初始化客户端
     */
    public Client() {
        try {//客户端连服务端,谁发起连接谁是客户端
            /*
             * 实例化Socket时需要传入两个参数:
             * 1:服务端的IP地址
             * 2:服务端的端口号
             * 通过IP地址可以找到服务端所在的计算机,通过端口可以找到运行在服务端
             * 的应用程序.
             * 注意:实例化Socket的过程就时连接的过程,若连接失败就会抛出异常
             */
            System.out.println("正在连接服务端...");
            socket = new Socket("localhost", 8088);//new的过程就是发起连接的过程
            System.out.println("与服务端连接成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
     * 客户端开始工作的方法
     */
    public void start() {
        try {
            /*
             * Socket提供的方法
             * OutputStream getOutputStream()
             * 该方法读取一个字节输出流,通过该流写出的数据会发送给远端计算机
             */
            OutputStream out = socket.getOutputStream();
            OutputStreamWriter osw = new OutputStreamWriter(out, "UTF-8");
            BufferedWriter bw = new BufferedWriter(osw);
            PrintWriter pw = new PrintWriter(bw,true);//聊天需要及时性

            pw.println("你好,服务端!");//必须使用println()方法===>br.readLine();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Client client = new Client();
        client.start();
    }
}

服务端:

package socket;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 聊天室服务端
 *
 * @author Mr.Huang
 * @date 2018年8月1日
 */
public class Server {
    /*
     * ServerSocket
     * 运行在服务端的ServerSocket主要有两个作用:
     * 1:向系统申请服务端口,客户端就是通过这个端口与服务端建立连接的.
     * 2:监听服务端口,一旦客户端与服务端建立连接,就会自动创建一个Socket,并通过该
     * Socket与建立连接的客户端进行交互
     */
    private ServerSocket serverSocket;

    /*
     * 用来初始化服务端
     */
    public Server(){
        try {
            /*
             * 实例化ServerSocket的同时深情服务端口
             */
            System.out.println("正在启动服务端...");
            serverSocket = new ServerSocket(8088);
            System.out.println("服务端启动完毕!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
     * 服务端开始工作的方法
     */
    public void start(){
        try {
            System.out.println("等待客户端连接...");
            Socket socket = serverSocket.accept();//阻塞方法
            System.out.println("与客户端连接成功!");
            /*
             * 接受客户端的输入
             * 通过Socket提供的方法:
             * InputStream getInputStream()
             * 读取该输入流的数据就是读取远端计算机发送过来的数据
             */
            InputStream is = socket.getInputStream();
            InputStreamReader isr = new InputStreamReader(is, "UTF-8");
            BufferedReader br = new BufferedReader(isr);

            String message = br.readLine();
            System.out.println("客户端说" + message);
            } catch (IOException e) {
                e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Server server = new Server();
        server.start();
    }
}