一、异常机制
1.基本概念
- 程序的异常行为
- java.lang.Throwable类是Error和Exception的超类
- Error用于描述java虚拟机无法解决的严重错误,通常无法编码解决,如JVM挂掉了等
- Exception类主要用于描述因编程错误或偶然外在因素导致的轻微错误,通常可以解决
2.异常的分类
(一)RuntimeException-运行时异常,也叫非检测性异常
- 主要子类
ArithmeticException类 - 算术异常
ArrayIndexOutOfBoundsException类 - 数组下标越界异常
NullPointerException - 空指针异常
ClassCastException - 类型转换异常
NumberFormatException - 数字格式异常
(二)IOException异常和其他异常,也叫检测性异常
注意:1. 在程序执行过程中发生异常但又没有手动处理时,则由Java虚拟机采用默认方式处理异常,而默认处理方式就是:打印异常的名称、发生的原因、发生的位置以及中止程序。
2,异常的避免 在以后的开发中尽量使用if条件判断来避免异常的发生。但是过多的if条件判断会导致程序的代码加长、臃肿,可读性差。
3.异常抛出
二、File类
1.概念
java.io.File类主要用于描述文件或目录路径的抽象表示信息,可以获取文件或目录的特征信息。
2.常用方法
- File(String pathname) 根据参数指定的路径名来构造对象
- File(String parent, String child) 根据参数指定的父路径和子路径信息构造对象
- File(File parent, String child) 根据参数指定的父抽象路径和子路径信息构造对象
- boolean exists() 测试此抽象路径名表示的文件或目录是否存在
- String getName() 用于获取文件的名称
- long length() 返回由此抽象路径名表示的文件的长度
- long lastModified() 用于获取文件的最后一次修改时间
- String getAbsolutePath() 用于获取绝对路径信息
- boolean delete() 用于删除文件,当删除目录时要求是空目录
- boolean createNewFile() 用于创建新的空文件
- boolean mkdir() 用于创建目录
- boolean mkdirs() 用于创建多级目录
- File[] listFiles() 获取该目录下的所有内容
- boolean isFile() 判断是否为文件
- boolean isDirectory() 判断是否为目录
- File[] listFiles(FileFilter filter) 获取目录下满足筛选器的所有内容
三、IO流
1.基本分类
- 三种分类方式:
1.按照读写数据的基本单位 分为字节流和字符流
字节流可读写任意类型的文件,而字符流只能读写文本文件。
2.按照读写数据的方向不同,分为输入流和输出流
3.按照流的角色不同分为节点流和处理流,节点流主要指直接和输入输出源对接的流;处理流指需要建立在节点流基础之上的流。
2.字节流
InputStream(抽象类)
- FileInputStream:主要用于从输入流中以字节流的方式读取图像数据
- BufferedInputStream:缓冲输入流
- DataInputStream:以适当的方式将基本数据类型写入输出流中
- ObjectInputStream:从输入流中一次性将对象读取出来
OutputStream(抽象类)
- FileOutputStream:主要用于将图像数据的原始字节流写入到输出流中
- BufferedOutputStream:缓冲输出流
- DataOutputStream:从输入流中读取基本数据类型的数据
- ObjectOutputStream:将对象的所有内容整体写入到输出流中(写入的对象类必须实现序列化接口,以及生成序列化UID)
- PrintStream:更加方便的打印各种数据内容
方法:print(String str) 和 println(String x)
3.字符流
Reader(抽象类)
- FileReader:主要用于从文本文件中读取数据内容
- BufferedReader:从缓冲输入流中读取单个字符、字符数组和字符串
- InputStreamReader:实现字节流向字符流的转换(可指定编码)
Writer(抽象类)
- FileWriter:主要用于将文本内容写入到文本文件。
- BufferedWriter:主要用于将单个字符、字符数组和字符串写入输出流
- OutputStreamWriter:实现字符流向字节流的转换(可指定编码)
- PrintWriter:将对象的格式化信息打印到文本输出流中
四、多线程
1.创建方式
- 自定义类继承Thread类,重写run方法,调用start方法启动线程
- 自定义类实现Runable接口,并重写run方法,创建该自定义类的对象,将其作为Thread构造方法中的参数来构造Thread对象,然后调用start方法
2.方式比较
实现Runable接口可扩展性强
3.线程生命周期
- 新建状态:使用new关键字之后的状态,此时线程并没有执行
- 就绪状态:调用start方法后进入的状态,此时线程还没有开始执行
- 运行:CPU调度算法分配了时间片之后开始执行
- 阻塞:线程运行期间发生阻塞 如调用sleep方法
- 消亡:线程运行结束后的状态
4.线程常用方法
Thread t=new Thread();
t.getId();//线程编号
t.getName();//线程名称
t.setName(String name);//修改线程名称
t.getPriority();//获取线程优先级,默认为5 最高为10
t.setPriority(int p);//设置优先级
t.join()//等待该线程结束
t.join(long m);//等待参数指定的时间
boolean flag=t.isDaemon();//判断该线程是否为守护线程
t.setDaemon(boolean f);//设置为守护线程
//获取当前正在执行线程的引用
Thread current=Thread.currentThread();
5.线程同步
(一) 基本概念
- 异步操作:多线程并发执行,各自独立
- 同步操作:多线程串行执行,具有先后执行顺序
(二)实现方式
使用synchronized关键字实现同步/对象锁机制
//1.使用同步代码块
synchronized(类类型的引用) {
编写所有需要锁定的代码;
}
//2.使用synchronized关键字修饰方法
public synchronized void show(){
//代码
}
//该方式等价于synchronized(this) { 整个方法体的代码 }
使用Lock实现线程同步
- 从java5开始提供显示定义的同步锁对象来实现
- java.util.concurrent.locks.Lock接口是控制多个线程访问共享资源的工具
- 该接口的主要实现类是ReentrantLock类,该类拥有与synchronized相同的并发性,在以后的线程安全控制中,经常使用ReentrantLock类显式加锁和释放锁。
主要方法
ReentrantLock() 使用无参方式构造对象
void lock() 获取锁
void unlock() 释放锁
synchronized方式与lock比较
- Lock是显式锁,需要手动开启和关闭操作,synchronized是隐式锁,执行完毕自动释放
- 使用Lock锁,java虚拟机将花费较少的时间来调度线程,性能更好
- Lock只有同步代码块的锁,而synchronized有同步代码块和同步方法两种锁
Object类常用的方法
wait() :用于使得线程进入等待状态,直到其它线程调用notify()或notifyAll()
wait(long timeout):用于进入等待状态,直到其它线程调用方法或参数指定的毫秒数已经过去为止
notify(): 用于唤醒等待的单个线程
notifyAll() :用于唤醒等待的所有线程
(三)静态方法的锁定
静态方法锁的是类对象而非静态方法锁的是当前方法所属对象。
注意事项:
使用synchronized保证线程同步应当注意:
多个需要同步的线程在访问同步块时,看到的应该是同一个锁对象引用。在使用同步块时应当尽量减少同步范围以提高并发的执行效率。
6.线程池
(一)实现Callable接口
- 自Java5开始新增加创建线程的第三种方式,为实现java.util.concurrent.Callable接口。
- 需要重写call()方法
(二)FutureTask类
该类提供了Future接口的基本实现,包括启动和取消计算、查询计算是否完成以及检索计算结果的方法,也可以用于获取方法调用后的返回结果
(三)概念
- 多个线程的集合,称为线程池。当服务器接收到一个客户请求后,就从线程池中取出一个空闲的集合为之服务,请求断开后,将该线程归还至线程池。
- 线程池的编程模式中,任务是提交给整个线程池,由线程池将任务分配给内部某个空闲的线程,可同时向线程池提交多个任务。
(四)相关类和方法
-
从Java5开始提供了线程池的相关类和接口:
1.Executors类
包含三个静态方法:
①ExecutorService newCachedThreadPool() 可根据需要创建新线程的线程池
②ExecutorService newFixedThreadPool(int n) 创建一个可重用固定线程数的线程池
③ExecutorService newSingleThreadExecutor() 线程池只包含一个线程2.java.util.concurrent.ExecutorService接口
-
其中Executors是个工具类和线程池的工厂类,可以创建并返回不同类型的线程池,常用方法如
-
execute(Runnable command)方法通常用于执行Runnable
-
Future submit(Callable task)通常用于执行Callable
-
shutdown() 启动有序关闭
五、网络编程
1.OSI模型和TCP/IP模型
2.TCP协议和UDP协议(简要)
(一)TCP(传输控制协议)
- 面向连接的协议
- 建立连接→进行通信→断开连接
- 传输前采用“三次握手”方式
- 通信过程中保持连接,形成数据传输通道
- 保证了数据传输的可靠性和有序性
- 一种全双工的字节流通信方式,可以进行大数据量的传输
- 传输结束后需要释放连接,发送数据效率比较低
(二)UDP(用户数据报协议)
- 无需建立连接
- 不保证数据传输的可靠性和有序性
- 全双工的数据报通信方式,每个数据报的大小限制在64K内
- 开销小,发送数据效率较高,速度快
3.基于TCP协议的编程模型
(一)编程模型
-
服务器:
1.创建ServerSocket类型的对象并提供端口号;
2.等待客户端连接,调用accept()方法 return Socket类型引用
3.使用输入输出流进行通信
4.关闭Socket -
客户端
1.创建Socket类型的对象并提供服务器的IP地址和端口号
2.使用输入输出流进行通信
3.关闭Socket;
(二) 相关类和方法的解析
1、ServerSocket
- ServerSocket(int port) 指定端口号构建对象
- Socket accept() 侦听并接收套接字的请求
- close() 关闭套接字
2、Socket
- InputStream getInputStream() 获取当前套接字的输入流
- OutputStream getOutputStream() 获取输出流
- close …
3、注意事项
- 客户端 Socket 与服务器端 Socket 对应, 都包含输入和输出流。
- 客户端的socket.getInputStream() 连接于服务器socket.getOutputStream()。
- 客户端的socket.getOutputStream()连接于服务器socket.getInputStream()
4.基于UDP协议
(一)编程模型
发送方
- 创建DatagramSocket类型的对象
- 创建DatagramPacket类型的对象并提供接收方的通信地址
- 通过Socket将packet中的内容发送出去,调用send方法
- 关闭Socket
接收方
- 创建DatagramSocket对象并提供端口号
- 创建DatagramPacket对象并提供缓冲区
- 通过Socket接收数据内容并放到packet中,调用receive方法
- 关闭Socket;
(二)相关类
1、DatagramSocket类
- net包中的DatagramSocket类主要用于描述发送和接收数据包的套接字
- DatagramSocket() 使用无参的方式构造对象
- DatagramSocket(int port) 根据参数指定的端口号来构造对象
- void receive(DatagramPacket p) 用于接收数据报存放到参数指定的位置
- void send(DatagramPacket p) 用于将参数指定的数据报发送出去
- void close() 关闭Socket并释放相关资源
2、DatagramPacket类 - 该类主要用于描述数据报
3、InetAddress类 - static InetAddress getLocalHost() 用于获取当前主机的通信地址
- static InetAddress getByName(String host) 根据参数指定的主机名获取通信地址
六、反射
1.概念
- 反射就是动态创建对象并且动态调用方法的机制
- 反射机制(动态编程技术)是在编写代码时不确定需要创建何种类型的对象,也不确定调用什么方法,希望由运行时传递的参数决定的一种机制。
- 主流框架底层都采用了反射机制
2.Class类
(一)基本概念
- java.lang.Class类的实例可用来描述Java应用程序的类和接口,也是一种数据类型
- Class类没有公共构造方法,该类的实例由java虚拟机和类加载器自动构造完成,本质是加载到内存中的运行时类
(二)获取方式
- 使用数据类型.class的方式可以获取对应类型的Class对象 *
- 使用 引用/对象.getClass()的方式可以获取对应类型的Class对象
- 使用包装类.TYPE的方式可以获取对应基本数据类型的Class对象
- 使用Class.forName()的方式来获取参数指定类型的Class对象
- 使用类加载器ClassLoader的方式获取指定类型的Class对象