Java 抽象类
-
抽象类: abstract修饰的类为抽象类,抽象类不能创建实例
-
抽象成员函数: abstract修饰的类为抽象成员函数,该成员函数为抽象成员函数,没有函数体。
-
抽象类与抽象成员函数有何联系: 有抽象函数的类必须被生命为抽象类,但是抽象函数中也可以有非抽象函数、也可以有构造函数。
-
抽象类可以有构造函数,可以通过构造函数初始化抽象类里的变量,主要是给子类通过
super()
调用。
Less than 1 minute
抽象类: abstract修饰的类为抽象类,抽象类不能创建实例
抽象成员函数: abstract修饰的类为抽象成员函数,该成员函数为抽象成员函数,没有函数体。
抽象类与抽象成员函数有何联系: 有抽象函数的类必须被生命为抽象类,但是抽象函数中也可以有非抽象函数、也可以有构造函数。
抽象类可以有构造函数,可以通过构造函数初始化抽象类里的变量,主要是给子类通过 super()
调用。
The Java collection can be roughly divided into four systems: Set, List, Queue and Map
Set
: unordered and unrepeatable; 无序,不可重复List
: ordered and repetable sets; 有序,可重复Map
: collections with mapping relations; 两个具有映射关系的集合Queue
: First in first out list(Java 5) FIFO队列instanceof 是一个二元修饰符,作用是用来判断左边的对象是否是右边类的实例,或者是右边超类的实例
分为BIO,NIO,AIO三种
传统 IO 基于字节流或字符流(如 FileInputStream、BufferedReader 等)进行文件读写,以及使用Socket 和 ServerSocket 进行网络传输。
传统 IO 采用阻塞式模型,对于每个连接,都需要创建一个独立的线程来处理读写操作。当一个线程在等待 I/O 操作时,无法执行其他任务。这会导致大量线程的创建和销毁,以及上下文切换,降低了系统性能。
因此传统IO也被称为BIO(Blocking IO)。
public class AioDemo {
public static void main(String[] args) {
AioDemo demo = new AioDemo();
demo.writeFile();
demo.readFile();
}
// 使用 AsynchronousFileChannel 写入文件
public void writeFile() {
// 使用 Paths.get() 获取文件路径
Path path = Paths.get("logs/itwanger/paicoding.txt");
try {
// 用 AsynchronousFileChannel.open() 打开文件通道,指定写入和创建文件的选项。
AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
// 将要写入的字符串("学编程就上技术派")转换为 ByteBuffer。
ByteBuffer buffer = StandardCharsets.UTF_8.encode("学编程就上技术派");
// 调用 fileChannel.write() 方法将 ByteBuffer 中的内容写入文件。这是一个异步操作,因此需要使用 Future 对象等待写入操作完成。
Future<Integer> result = fileChannel.write(buffer, 0);
// 等待写操作完成
result.get();
System.out.println("写入完成");
fileChannel.close();
} catch (IOException | InterruptedException | java.util.concurrent.ExecutionException e) {
e.printStackTrace();
}
}
// 使用 AsynchronousFileChannel 读取文件
public void readFile() {
Path path = Paths.get("logs/itwanger/paicoding.txt");
try {
// 指定读取文件的选项。
AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);
// 创建一个 ByteBuffer,用于存储从文件中读取的数据。
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 调用 fileChannel.read() 方法从文件中异步读取数据。该方法接受一个 CompletionHandler 对象,用于处理异步操作完成后的回调。
fileChannel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
// 在 CompletionHandler 的 completed() 方法中,翻转 ByteBuffer(attachment.flip()),然后使用 Charset.forName("UTF-8").decode() 将其解码为字符串并打印。最后,清空缓冲区并关闭文件通道。
attachment.flip();
System.out.println("读取的内容: " + StandardCharsets.UTF_8.decode(attachment));
attachment.clear();
try {
fileChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
// 如果异步读取操作失败,CompletionHandler 的 failed() 方法将被调用,打印错误信息。
System.out.println("读取失败");
exc.printStackTrace();
}
});
// 等待异步操作完成
Thread.sleep(1000);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
public class BioFileDemo {
public static void main(String[] args) {
BioFileDemo demo = new BioFileDemo();
demo.writeFile();
demo.readFile();
}
// 使用 BIO 写入文件
public void writeFile() {
String filename = "logs/itwanger/paicoding.txt";
try {
FileWriter fileWriter = new FileWriter(filename);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write("学编程就上技术派");
bufferedWriter.newLine();
System.out.println("写入完成");
bufferedWriter.close();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 使用 BIO 读取文件
public void readFile() {
String filename = "logs/itwanger/paicoding.txt";
try {
FileReader fileReader = new FileReader(filename);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println("读取的内容: " + line);
}
bufferedReader.close();
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
NIO 主要有两个核心部分组成:
在 NIO 中,并不是以流的方式来处理数据的,而是以 buffer 缓冲区和 Channel 通道配合使用来处理数据的。Channel 不与数据打交道,它只负责运输数据。与数据打交道的是 Buffer 缓冲区。相对于传统 IO 而言,流是单向的。对于 NIO 而言,有了 Channel 通道这个概念,我们的读写都是双向的。