1、异常
可检测异常:不可控错误,无法在逻辑层面解决所有问题;
非检测异常:逻辑错误Bug,可以通过代码完全避免;常见的有RuntimeException;
RuntimeException异常子类:
NullPointerException - 空指针引用异常
ClassCastException - 类型强制转换异常。
IllegalArgumentException - 传递非法参数异常。
ArithmeticException - 算术运算异常
ArrayStoreException - 向数组中存放与声明类型不兼容对象异常
IndexOutOfBoundsException - 下标越界异常
NegativeArraySizeException - 创建一个大小为负数的数组错误异常
NumberFormatException - 数字格式异常
SecurityException - 安全异常
UnsupportedOperationException - 不支持的操作异常
自定义异常:常用于满足语法但不满足需求时,自己去自定义一个新异常;要求异常类名需要做到见名知义;它继承自Exception(直接或间接继承);提供所有构造器(IDEA生成即可);
public class IllegalAgeException extends Exception{
public IllegalAgeException() {
}
public IllegalAgeException(String message) {
super(message);
}
public IllegalAgeException(String message, Throwable cause) {
super(message, cause);
}
public IllegalAgeException(Throwable cause) {
super(cause);
}
public IllegalAgeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
抛出自定义异常:
public class Person {
private int age;
public int getAge() {
return age;
}
/*
针对一个单独的特类异常,声明里的throws异常最好也写成相应的异常
*/
public void setAge(int age) throws IllegalAgeException {
if(age<0||age>100){
throw new IllegalAgeException();
}
this.age = age;
}
}
2、网络编程基础
Client:客户端 Server:服务端
传输协议:
(TCP)可靠传输:效率低,需要反复确认;
(UDP)不可靠传输:效率高,但可能会丢包,网络程序主流协议;
java.net.Socket:Socket(套接字)封装了TCP协议的通讯细节,使用它可以与服务端建立网络链接,并获取两个流(一个输入一个输出),然后使用这两个流的读写操作完成与服务端的数据交互;
Socket提供了两个重要的方法:
OutputStream getOutputStream();
该方法会获取一个字节输出流,通过这个输出流写出的字节数据会通过网络发送给对方。
InputStream getInputStream();
通过该方法获取的字节输入流读取的是远端计算机发送过来的数据。
java.net.ServerSocket:运行在服务端,它的作用有两个:
1:向系统申请服务端口,客户端的Socket就是通过这个端口与服务端建立连接的。
2:监听服务端口,一旦一个客户端通过该端口建立连接则会自动创建一个Socket,并通过该Socket与客户端进行数据交互。
实例化ServerSocket时要指定服务端口,端口是一个数字,取值范围:0-65535之间;6000之前的的端口不要使用,密集绑定系统应用和流行应用程序;该端口不能与操作系统其它应用程序占用的端口相同,否则会抛出异常:java.net.BindException:address already in use
ServerSocket提供了接受客户端链接的方法:Socket accept()
这个方法是一个阻塞方法,调用后方法"卡住",此时开始等待客户端的链接,直到一个客户端链接,此时该方法会立即返回一个Socket实例,通过这个Socket就可以与客户端进行交互了;
先创建一个简易的网络聊天室:一个服务端和一个客户端,客户端可以链接服务端并发送消息;
服务端:
public class Server {
private ServerSocket serverSocket;
public Server(){
try {
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("一个客户端链接了!");
InputStream in = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(in, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr);
String line;
/*
这里我们使用BufferedReader的readLine试图读取来自远端计算机
发送过来的一行字符串时,如果对方链接还保持着,但是没有发送任何
内容时,这里的readLine会阻塞。
客户端断开链接时,服务端的readLine方法可能出现以下几种情况:
最正常的情况:客户端调用了socket的close方法与服务端断开链接
socket的close方法会进行底层TCP的挥手动作与对方断开链接。
那么readLine方法这里会立即返回null,表示链接断开了。不能再读取数据了
客户端若异常断开链接,在没有调用socket.close()就结束了程序,那么
服务端这里的readLine()方法会抛出异常:
java.net.SocketException: Connection reset
*/
while((line = br.readLine())!=null) {
System.out.println("客户端说:" + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
}
客户端:
public class Cli {
private S