黑马程序员Java教程学习笔记(六)

学习视频:https://www.bilibili.com/video/BV1Cv411372m
如侵权,请私信联系本人删除

文章目录


黑马程序员Java教程学习笔记(六)

File概述、File对象创建

  • File类可以定位文件:进行删除、获取文本本身信息等操作
  • 但是不能读写文件内容
  • 使用IO流技术可以对硬盘中的文件进行读写

File类概述:

  • File类在包java.io.File下,代表操作系统的文件对象(文件、文件夹)
  • File类提供了诸如:定位文件、获取文件本身的信息、删除文件、创建文件(文件夹)等功能

在这里插入图片描述
注意:File创建对象,支持绝对路径,也支持相对路径

package com.mochu.d1_file;

import java.io.File;

public class FileDemo {
    public static void main(String[] args) {
        // 创建File对象(指定了文件的路径)
        File f = new File("C:\\Users\\Administrator\\Downloads\\Asuna.jpg");
        // 一般不使用File.separator 但是在一些跨平台Linux Windows都是用的情况下File.separator比较方便
        // File f1 = new File("C:" + File.separator + "Users" + File.separator + "Administrator" + File.separator + "Downloads");
        long fileSize = f.length();
        System.out.println("文件大小:" + fileSize);

        // 相对路径一般定位模块中的文件,相对在工程下(从工程目录开始)
        File f2 = new File("File-IO-App\\src\\data.txt");
        System.out.println(f2.length());

        // File对象可以是文件也可以是文件夹(目录)
        File f3 = new File("C:\\Users\\Administrator\\Downloads");
        System.out.println("文件夹是否存在:" + f3.exists());
    }
}

在这里插入图片描述

File类的常用方法

在这里插入图片描述

package com.mochu.d1_file;

import java.io.File;
import java.text.SimpleDateFormat;

public class FileDemo01 {
    public static void main(String[] args) {
        File f1 = new File("C:\\Users\\Administrator\\Downloads\\Asuna.jpg");
        // 获取绝对路径
        System.out.println(f1.getAbsoluteFile());
        // 获取文件定义时的路径
        System.out.println(f1.getPath());
        // 获取文件的名称(带后缀)
        System.out.println(f1.getName());
        // 获取文件的字节大小
        System.out.println("文件的字节大小:" + f1.length());
        // 获取文件的最后修改时间
        long time = f1.lastModified();
        System.out.println("最后修改时间:" + new SimpleDateFormat("yy/MM/dd HH:mm:ss").format(time));
        // 判断是文件还是文件夹
        System.out.println(f1.isFile());
        System.out.println(f1.isDirectory());
        System.out.println(f1.exists());
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d1_file;

import java.io.File;
import java.io.IOException;

public class FileDemo02 {
    public static void main(String[] args) throws IOException {
        File f = new File("C:\\Users\\Administrator\\Downloads\\flag.txt");
        File f1 = new File("C:\\Users\\Administrator\\Downloads\\1.txt");
        System.out.println(f.createNewFile());
        System.out.println(f1.createNewFile());

        // 创建一级目录
        File f2 = new File("C:\\Users\\Administrator\\Downloads\\test");
        System.out.println(f2.mkdir());
        // 创建多级目录
        File f3 = new File("C:\\Users\\Administrator\\Downloads\\test\\test");
        System.out.println(f2.mkdirs());

        // 删除文件或者空文件夹
        File f4 = new File("C:\\Users\\Administrator\\Downloads\\test\\test");
        File f5 = new File("C:\\Users\\Administrator\\Downloads\\1.txt");
        System.out.println(f4.delete());
        System.out.println(f5.delete());
    }
}

在这里插入图片描述

package com.mochu.d1_file;

import java.io.File;
import java.io.IOException;

public class FileDemo02 {
    public static void main(String[] args) throws IOException {
        // 遍历目录
        File f = new File("C:\\Users\\Administrator\\Downloads");
        String[] names = f.list();
        for (String name : names) {
            System.out.println(name);
        }

        // 获取当前目录下的每个文件对象
        File f1 = new File("C:\\Users\\Administrator\\Downloads");
        File[] files = f1.listFiles();
        for (File file : files) {
            System.out.println(file.getAbsoluteFile());
        }
    }
}

方法递归

在这里插入图片描述
在这里插入图片描述

package com.mochu.d2_recursion;

public class RecursionDemo01 {
    public static void main(String[] args) {
        System.out.println(f(5));
    }

    public static int f(int n) {
        if(n == 1) {
            return 1;
        }else {
            return f(n - 1) * n;
        }
    }
}

在这里插入图片描述

package com.mochu.d2_recursion;

public class RecursionDemo01 {
    public static void main(String[] args) {
        System.out.println(f(100));
    }

    public static int f(int n) {
        if(n == 1) {
            return 1;
        }else {
            return f(n - 1) + n;
        }
    }
}

在这里插入图片描述

f(x) - f(x)/2 - 1 = f(x+1)
2f(x) - f(x) - 2 = 2f(x + 1)
f(x) = 2f(x + 1) + 2

求f(1) = ?
终结点: f(10) = 1
package com.mochu.d2_recursion;

public class RecursionDemo01 {
    public static void main(String[] args) {
        System.out.println(f(1));
        System.out.println(f(2));
        System.out.println(f(3));
    }

    public static int f(int n) {
        if(n == 10) {
            return 1;
        }else {
            return 2 * f(n + 1) + 2;
        }
    }
}

非规律化递归问题:文件搜索

在这里插入图片描述

package com.mochu.d2_recursion;

import java.io.File;
import java.io.IOException;

public class RecursionDemo01 {
    public static void main(String[] args) {
        File f = new File("D:\\KuGou\\");
        searchFile(f, "KuGou.exe");
    }

    /**
     * 搜索某个目录下的所有文件
     * @param dir 被搜索的目录
     * @param fileName 被搜索的文件名称
     */
    public static void searchFile(File dir, String fileName) {
        // 判断dir是否是目录
        if(dir.isDirectory() && dir != null) {
            File[] files = dir.listFiles();
            if(files != null && files.length > 0) {
                for (File file : files) {
                    // 判断当前的一级目录文件对象是文件还是文件夹
                    if(file.isFile()) {
                        if(file.getName().contains(fileName)) {
                            System.out.println(file.getAbsoluteFile());
                            try {
                                Runtime r = Runtime.getRuntime();
                                r.exec(file.getAbsolutePath());
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }else {
                        // 递归
                        searchFile(file, fileName);
                    }
                }
            }
        }else {
            System.out.println("您当前的目录有误");
        }
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d2_recursion;

public class RecursionDemo02 {
    public static int totalNumber; // 总数量
    public static int lastBottleNumber; // 记录每次剩余瓶子数
    public static int lastConverNumber; // 记录每次剩余盖子数

    public static void main(String[] args) {
        buy(10);
        System.out.println("总数: " + totalNumber);
        System.out.println("剩余盖子数:" + lastConverNumber);
        System.out.println("剩余瓶子数:" + lastBottleNumber);
    }

    public static void buy(int money){
        int buyNumber = money / 2;
        totalNumber += buyNumber;

        int coverNumber = lastConverNumber + buyNumber;
        int bottleNumber = lastBottleNumber + buyNumber;

        int allMoney = 0;
        if(coverNumber >= 4) {
            allMoney += (coverNumber / 4) * 2;
        }
        lastConverNumber = coverNumber % 4;

        if(bottleNumber >= 2) {
            allMoney += (bottleNumber / 2) * 2;
        }
        lastBottleNumber = bottleNumber % 2;

        if(allMoney >= 2) {
            buy(allMoney);
        }
    }
}

IO前置内容:字符集

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d3_charset;

import java.util.Arrays;

public class Test {
    public static void main(String[] args) throws Exception{
        // 文字转换成字节(使用指定编码)
        String name = "末初mochu7";
        // byte[] bytes = name.getBytes(); // 以默认字符集编码
        byte[] bytes = name.getBytes("GBK"); // 以默认字符集编码
        System.out.println(bytes.length);
        System.out.println(Arrays.toString(bytes));

        // 把字节转换成文字(注意:编码前和解码的字符集需要一致,否则乱码)
        // String rs = new String(bytes);
        String rs = new String(bytes, "GBK"); // 指定解码字符集
        System.out.println(rs);
    }
}

在这里插入图片描述

IO流分类、文件字节输入流、读取字节数据、避免乱码的方案

  • IO流也称为输入、输出流,就是用来读写数据的
  • I表示input,是数据从硬盘文件读入到内存的过程,称为输入、负责读
  • O表示output,是内存程序的数据从内存到写出硬盘文件的过程,称为输出,负责写

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d4_bytestream;

import java.io.FileInputStream;
import java.io.InputStream;

public class Test {
    public static void main(String[] args) throws Exception{
        InputStream is = new FileInputStream("File-IO-App/src/data.txt");
        int b1 = is.read();
        System.out.println(b1);
        System.out.println((char) b1);

        int b2 = is.read();
        System.out.println((char) b2);

        int b3 = is.read();
        System.out.println((char) b3);

        // 循环读取
        InputStream is1 = new FileInputStream("File-IO-App/src/data.txt");
        int b;
        while((b = is1.read()) != -1) {
            System.out.print((char) b);
        }
    }
}

在这里插入图片描述

package com.mochu.d4_bytestream;

import java.io.FileInputStream;
import java.io.InputStream;

public class ByteStreamDemo {
    public static void main(String[] args) throws Exception {
        InputStream is = new FileInputStream("File-IO-App/src/data.txt");

        // 定一个字节数组,用于读取字节数据
        byte[] buffer = new byte[4];
        int len;
        while((len = is.read(buffer)) != -1) {
            System.out.print(new String(buffer, 0, len));
        }
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d4_bytestream;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class ByteStreamDemo {
    public static void main(String[] args) throws Exception {
        File f = new File("File-IO-App/src/data.txt");
        InputStream is = new FileInputStream(f);

//        byte[] buffer = new byte[(int) f.length()];
//        int len = is.read(buffer);
//        System.out.println("读取了" + len + "个字节");
//        System.out.println("文件大小:" + f.length());
//        System.out.println(new String(buffer));

        byte[] buffer = is.readAllBytes();
        System.out.println(new String(buffer));
    }
}

文件字节输出流、文件拷贝、释放资源的2种方式

在这里插入图片描述

package com.mochu.d5_outputstream;

import java.io.*;

public class OutStreamDemo {
    public static void main(String[] args) throws Exception {
        // 创建一个文件字节输出流管道与目标文件接通
        OutputStream os = new FileOutputStream("File-IO-App/src/flag.txt", true); // true: 追加管道
        os.write('a');
        os.write(98);
        os.write("\r\n".getBytes());

        byte[] buffer = {'f', 'l', 'a', 'g'};
        // 刷新、释放资源
        // os.flush();
        os.write(buffer);
        byte[] buffer2 = "末初".getBytes();
        os.write(buffer2);
        os.close();
    }
}

文件拷贝

package com.mochu.d5_outputstream;

import java.io.*;

public class CopyDemo {
    public static void main(String[] args) throws Exception {
        try {
            InputStream is = new FileInputStream("C:\\Users\\Administrator\\Downloads\\Asuna.jpg");
            OutputStream os = new FileOutputStream("C:\\Users\\Administrator\\Downloads\\Asuna-copy.jpg");

            byte[] buffer = new byte[1024];
            int len;
            while((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            System.out.println("复制完成");
            os.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

资源释放的方式

在这里插入图片描述

package com.mochu.resource;

import java.io.*;

public class TryCatchFinallyDemo {
    public static void main(String[] args) throws Exception {
        InputStream is = null;
        OutputStream os = null;
        try {
            is = new FileInputStream("C:\\Users\\Administrator\\Downloads\\Asuna.jpg");
            os = new FileOutputStream("C:\\Users\\Administrator\\Downloads\\Asuna-copy.jpg");
            byte[] buffer = new byte[1024];
            int len;
            while((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            System.out.println(10 / 0);
            System.out.println("复制完成");
            os.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            // 无论代码是否正常结束,都会执行这里
            // 哪怕上面有return,也必须执行完这里才行,开发中不建议这里return
            System.out.println("===============Finally===============");
            try {
                if(is != null) is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(os != null) os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

在这里插入图片描述

package com.mochu.resource;

import java.io.*;

public class TryCatchFinallyDemo {
    public static void main(String[] args) throws Exception {
        try(
                InputStream is = new FileInputStream("C:\\Users\\Administrator\\Downloads\\Asuna.jpg");
                OutputStream os = new FileOutputStream("C:\\Users\\Administrator\\Downloads\\Asuna-copy.jpg");
                MyConnection connection = new MyConnection();
                ) {
            byte[] buffer = new byte[1024];
            int len;
            while((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            System.out.println("复制完成了");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class MyConnection implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("链接资源被成功释放");
    }
}
package com.mochu.resource;

import java.io.*;

public class TryCatchFinallyDemo {
    public static void main(String[] args) throws Exception {
        InputStream is = new FileInputStream("C:\\Users\\Administrator\\Downloads\\Asuna.jpg");
        OutputStream os = new FileOutputStream("C:\\Users\\Administrator\\Downloads\\Asuna-copy.jpg");
        try(is; os) {
            byte[] buffer = new byte[1024];
            int len;
            while((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            System.out.println("复制完成了");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

文件字符输入流、文件字符输出流

在这里插入图片描述

package com.mochu.d6_char_stream;

import java.io.FileReader;
import java.io.Reader;

public class FileReaderDemo {
    public static void main(String[] args) throws Exception {
        Reader fr = new FileReader("C:\\Users\\Administrator\\Downloads\\text.txt");
//        int code = fr.read(); // 读取一个字节
//        System.out.println((char) code);
        int code;
        while((code = fr.read()) != -1) {
            System.out.print((char) code);
        }
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d6_char_stream;

import java.io.FileReader;
import java.io.Reader;

public class FileReaderDemo {
    public static void main(String[] args) throws Exception {
        Reader fr = new FileReader("C:\\Users\\Administrator\\Downloads\\text.txt");
        char[] buffer = new char[1024]; // 1K字符
        int len;
        while((len = fr.read(buffer)) != -1) {
            String rs = new String(buffer, 0, len);
            System.out.print(rs);
        }
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d6_char_stream;

import java.io.FileWriter;
import java.io.Writer;

public class FileWriterDemo {
    public static void main(String[] args) throws Exception {
        // Writer fw = new FileWriter("C:\\Users\\Administrator\\Downloads\\1.txt");
        Writer fw = new FileWriter("C:\\Users\\Administrator\\Downloads\\1.txt", true);
        fw.write(100);
        fw.write('m');
        fw.write('末');
        fw.write("\r\n");
        fw.write("末初mochu7");

        char[] chars = "末初mochu7".toCharArray();
        fw.write(chars);
        fw.write("\r\n");
        fw.write("末初mochu7", 0, 3);

        fw.write(chars, 0, 2);

        // fw.flush(); // 刷新后流可以使用
        fw.close(); // 关闭后流不可以使用
    }
}

缓冲流的分类、字节缓冲流使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d1_byte_buffer;

import java.io.*;

public class ByteBuffDemo {
    public static void main(String[] args) throws Exception {
        try {
            InputStream is = new FileInputStream("C:\\Users\\Administrator\\Downloads\\Asuna.jpg");
            InputStream bis = new BufferedInputStream(is);
            OutputStream os = new FileOutputStream("C:\\Users\\Administrator\\Downloads\\Asuna-copy.jpg");
            OutputStream bos = new BufferedOutputStream(os);

            byte[] buffer = new byte[1024];
            int len;
            while((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            System.out.println("复制完成");
            os.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

字节缓冲流的性能分析

在这里插入图片描述

package com.mochu.d7_ByteBufferTime;

import java.io.*;

public class ByteBufferTimeDemo {
    private static final String SRC_FILE = "C:\\Users\\Administrator\\Downloads\\disk.flag.img";
    private static final String DEST_FILE = "C:\\Users\\Administrator\\Downloads\\";

    public static void main(String[] args) {
        // copy01(); //使用低级字节流按照一个一个字节的形式复制文件 // 最慢
        // copy02(); //使用低级字节流按照一个一个字节数组的形式复制文件  // 第二快
        // copy03(); //使用缓冲流按照一个一个字节的形式复制文件 // 倒数第二慢
        copy04(); //使用缓冲流按照一个一个字节数组的形式复制文件 // 最快
    }

    private static void copy04() {
        long startTime = System.currentTimeMillis();
        try(
                InputStream is = new FileInputStream(SRC_FILE);
                InputStream bis = new BufferedInputStream(is);
                OutputStream os = new FileOutputStream(DEST_FILE + "copy04-disk.flag.img");
                OutputStream bos = new BufferedOutputStream(os);
        ) {
            byte[] buffer = new byte[1024];
            int len;
            while((len = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("使用缓冲流按照一个一个字节数组的形式复制文件耗时:" + (endTime - startTime) / 1000.0 + 's');
    }

    /**
     * 使用缓冲流按照一个一个字节的形式复制文件
     */
    private static void copy03() {
        long startTime = System.currentTimeMillis();
        try(
                InputStream is = new FileInputStream(SRC_FILE);
                InputStream bis = new BufferedInputStream(is);
                OutputStream os = new FileOutputStream(DEST_FILE + "copy03-disk.flag.img");
                OutputStream bos = new BufferedOutputStream(os);
        ) {
            int len;
            while((len = bis.read()) != -1) {
                bos.write(len);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("使用缓冲字节流按照一个一个字节的形式复制文件耗时:" + (endTime - startTime) / 1000.0 + 's');
    }

    /**
     * 使用低级字节流按照一个一个字节数组的形式复制文件
     */
    private static void copy02() {
        long startTime = System.currentTimeMillis();
        try(
                InputStream is = new FileInputStream(SRC_FILE);
                OutputStream os = new FileOutputStream(DEST_FILE + "copy02-disk.flag.img");
        ) {
            byte[] buffer = new byte[1024];
            int len;
            while((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("使用低级字节流按照一个一个字节数组的形式复制文件:" + (endTime - startTime) / 1000.0 + 's');
    }

    /**
     * 使用低级字节流按照一个一个字节的形式复制文件
     */
    private static void copy01() {
        long startTime = System.currentTimeMillis();
        try(
                InputStream is = new FileInputStream(SRC_FILE);
                OutputStream os = new FileOutputStream(DEST_FILE + "copy01-disk.flag.img");
                ) {
                int len;
                while((len = is.read()) != -1) {
                    os.write(len);
                }
        }catch (Exception e){
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println(" 使用低级字节流按照一个一个字节的形式复制文件耗时:" + (endTime - startTime) / 1000.0 + 's');
    }
}

在这里插入图片描述

字符缓冲流

在这里插入图片描述

package com.mochu.d8_CharBufferStream;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class CharBufferStreamDemo {
    public static void main(String[] args) {
        try(
                Reader fr = new FileReader("File-IO-App/src/data.txt");
                BufferedReader br = new BufferedReader(fr);
                ) {
//            char[] buffer = new char[1024];
//            int len;
//            while((len = br.read(buffer)) != -1) {
//                String rs = new String(buffer, 0, len);
//                System.out.println(rs);
//            }
            String line;
            while((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

package com.mochu.d2_CharBufferStream;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.Writer;

public class CharBufferStreamDemo {
    public static void main(String[] args) throws Exception {
        Writer fw = new FileWriter("IO-App/src/data1.txt");
        BufferedWriter bw = new BufferedWriter(fw);

        bw.write(98);
        bw.write('a');
        bw.write('初');
        bw.write("末初mochu7");
        bw.newLine();

        bw.close();
    }
}

代码与文件编码不一致读取乱码问题、转换流

在这里插入图片描述

package com.mochu.d3_TransferStream;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class CharSetTest {
    public static void main(String[] args) throws Exception {
        try(
                Reader fr = new FileReader("C:\\Users\\Administrator\\Downloads\\flag.txt");
                BufferedReader bfr = new BufferedReader(fr);
                ) {
            String line;
            while((line = bfr.readLine()) != null) {
                System.out.println(line);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d3_TransferStream;

import java.io.*;

public class InputStreamReaderDemo {
    public static void main(String[] args) throws Exception {
        InputStream is = new FileInputStream("C:\\Users\\Administrator\\Downloads\\flag.txt");
        Reader fr = new InputStreamReader(is, "GBK"); // 指定GBK转化字符输入流
        BufferedReader br = new BufferedReader(fr);
        String line;
        while((line = br.readLine()) != null) {
            System.out.println(line);
        }
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d3_TransferStream;

import java.io.*;

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws Exception{
        OutputStream os = new FileOutputStream("IO-APP/src/test.txt");
        Writer osw = new OutputStreamWriter(os, "GBK");
        BufferedWriter bw = new BufferedWriter(osw);

        bw.write("mochu7");
        bw.write("末初");
        bw.close();
    }
}

对象序列化、反序列化

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

package com.mochu.d4_serialize;

import java.io.Serializable;

/**
 * 对象要序列化需要实现Serializable接口
 */
public class Student implements Serializable {
    private String name;
    private String loginName;
    private String passWord;
    private int age;
	
	.......
}
package com.mochu.d4_serialize;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class ObjectOutputStreamDemo{
    public static void main(String[] args) throws Exception{
        Student stu = new Student("mochu7", "mochu7", "mochu777", 22);

        // 对象序列化,使用对象字节输出流管道
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("IO-App/src/obj.txt"));
        oos.writeObject(stu);
        oos.close();
    }
}

在这里插入图片描述

package com.mochu.d4_serialize;

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class ObjectInputStreamDemo {
    public static void main(String[] args) throws Exception {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("IO-App/src/obj.txt"));

        // 调用对象字节输入流的反序列化方法
        Student stu = (Student) ois.readObject();
        System.out.println(stu);
    }
}

在这里插入图片描述

如果不想类中的某个属性被序列化,使用transient关键字:private transient String passWord;

// 声明序列化版本号码
// 序列化版本号与反序列化版本号必须一致才不会出错

private static final long serialVersionUID = 1;

打印流、Properties、commons-io框架

打印流:

  • 作用:打印流可以实现方便、高效的打印数据到文件中去,打印流一般是指:PrintStreamPrintWriter两个类

在这里插入图片描述

package com.mochu.d6_PrintStream;

import java.io.FileOutputStream;
import java.io.PrintStream;

public class PrintStreamDemo {
    public static void main(String[] args) throws Exception{
        PrintStream ps = new PrintStream(new FileOutputStream("IO-App/src/ps.txt"));
        // PrintStream ps = new PrintStream(new FileOutputStream("IO-App/src/ps.txt"), "GBK");
        ps.print(97);
        ps.println("mochu7");
        ps.println(35.5);
        ps.println("末初");
        ps.close();
    }
}

在这里插入图片描述

package com.mochu.d6_PrintStream;

import java.io.FileOutputStream;
import java.io.PrintWriter;

public class PrintStreamDemo {
    public static void main(String[] args) throws Exception{
        PrintWriter ps = new PrintWriter(new FileOutputStream("IO-App/src/ps1.txt"));
        ps.print(97);
        ps.println("mochu7");
        ps.println(35.5);
        ps.println("末初");
        ps.close();
    }
}

在这里插入图片描述

输出语句的重定向

package com.mochu.d6_PrintStream;

import java.io.PrintStream;

public class PrintDemo {
    public static void main(String[] args) throws Exception{
        System.out.println("mochu7");
        System.out.println("Slevin");

        // 改变输出语句的位置(重定向)
        PrintStream ps = new PrintStream("IO-App/src/log.txt");
        System.setOut(ps); // 把系统的打印流改成我们自己设定的

        System.out.println("test");
        System.out.println("test1");
    }
}

Properties

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d7_Properties;

import java.io.FileWriter;
import java.util.Properties;

public class PropertiesDemo {
    public static void main(String[] args) throws Exception {
        Properties properties = new Properties();
        properties.setProperty("mochu7", "mochu777");
        properties.setProperty("Slevin", "Slevin666");
        properties.setProperty("Shinn", "Shinn888");
        System.out.println(properties);

        properties.store(new FileWriter("IO-App/src/users.properties"), "users properties");
    }
}
package com.mochu.d7_Properties;

import java.io.FileReader;
import java.util.Properties;

public class PropertiesDemo01 {
    public static void main(String[] args) throws Exception {
        Properties properties = new Properties();

        properties.load(new FileReader("IO-App/src/users.properties"));

        System.out.println(properties);
        String rs = properties.getProperty("mochu7");
        System.out.println(rs);
    }
}

Commons-IO框架

在这里插入图片描述
Commons-IO: https://commons.apache.org/proper/commons-io/
在这里插入图片描述

package com.mochu.d8_CommonsIO;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Files;
import java.nio.file.Path;

public class CommonsIODemo {
    public static void main(String[] args) throws Exception {
        // 文件复制
        IOUtils.copy(new FileInputStream("IO-App/src/data.txt"), new FileOutputStream("IO-App/src/data2.txt"));

        // 文件复制到文件夹
        FileUtils.copyFileToDirectory(new File("IO-App/src/data.txt"), new File("C:/Users/Administrator/Downloads/"));

        // 文件夹复制到文件夹
        FileUtils.copyDirectoryToDirectory(new File("D:/Album/"), new File("C:/Users/Administrator/Downloads/"));

        // 删除文件夹
        FileUtils.deleteDirectory(new File("C:/Users/Administrator/Downloads/Album"));

        // JDK 1.7 新增的一些关于文件操作的API:NIO
        Files.copy(Path.of("IO-App/src/data.txt"), Path.of("IO-App/src/data3.txt"));

    }
}

线程概述、线程的创建方式

在这里插入图片描述

线程创建方式一:继承Thread类

在这里插入图片描述

package com.mochu.d1_create;

public class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("子线程输出:" + i);
        }
    }
}
package com.mochu.d1_create;

/**
 * 多线程的创建方式一:继承Thread
 */
public class ThreadDemo {
    public static void main(String[] args) {
        Thread t1 = new MyThread();
        t1.start();

        for (int i = 0; i < 5; i++) {
            System.out.println("[+]主线程输出:" + i);
        }
    }
}

在这里插入图片描述
在这里插入图片描述

线程创建方式二:实现Runmable接口

在这里插入图片描述

package com.mochu.d1_create;

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("子线程:" + i);
        }
    }
}
package com.mochu.d1_create;

public class ThreadDemo2 {
    public static void main(String[] args) {
        // 创建一个任务对象,然后把人物对象交给线程对象
        Runnable target = new MyRunnable();
        Thread t = new Thread(target);
        t.start();

        for (int i = 0; i < 5; i++) {
            System.out.println("[+]主线程输出:" + i);
        }
    }
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d1_create;

public class ThreadDemo2 {
    public static void main(String[] args) {
        // 创建一个任务对象,然后把人物对象交给线程对象
        Runnable target = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println("子线程1输出:" + i);
                }
            }
        };

        // 简化
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println("子线程2输出:" + i);
                }
            }
        }).start();

        // 再简化
        new Thread(() -> {
                for (int i = 0; i < 5; i++) {
                    System.out.println("子线程3输出:" + i);
            }
        }).start();


        for (int i = 0; i < 5; i++) {
            System.out.println("[+]主线程输出:" + i);
        }
    }
}

线程创建方式三:实现Callable、FutureTask接口

在这里插入图片描述

package com.mochu.d1_create;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

public class ThreadDemo3 {
    public static void main(String[] args) {
        // 创建Callable任务对象
        Callable<String> call = new MyCallable(100);
        // 把Callable任务对象封装成FutureTask对象
        // FutureTask对象的作用:是Runnable对象(实现了Runnable接口)
        // FutureTask对象的作用:可以在线程执行完毕之后,可以通过调用get方法得到线程执行完的结果
        FutureTask<String> f1 = new FutureTask<>(call);
        Thread t1 = new Thread(f1);
        t1.start();

        Callable<String> call1 = new MyCallable(200);
        FutureTask<String> f2 = new FutureTask<>(call1);
        Thread t2 = new Thread(f2);
        t2.start();

        try {
            String rs1 = f1.get();
            System.out.println("第一个结果:" + rs1);
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            String rs2 = f2.get();
            System.out.println("第一个结果:" + rs2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class MyCallable implements Callable<String> {
    private int n;

    public MyCallable(int n) {
        this.n = n;
    }

    // 实现Callable接口,声明线程执行完毕之后的返回类型
    @Override
    public String call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= n; i++) {
            sum += i;
        }
        return "子线程执行的结果是:" + sum;
    }
}

在这里插入图片描述
在这里插入图片描述

线程常用方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d2_api;

public class MyThread extends Thread{
    public MyThread() {
    }

    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + "子线程输出:" + i);
        }
    }
}
package com.mochu.d2_api;

public class ThreadDemo {
    public static void main(String[] args) {
        Thread t = new MyThread("1号");
        // t.setName("一号");
        t.start();

        Thread t1 = new MyThread("2号");
        // t1.setName("二号");
        t1.start();

        Thread m = Thread.currentThread();
        System.out.println(m.getName());

        for (int i = 0; i < 5; i++) {
            System.out.println("主线程输出:" + i);
        }
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d2_api;

public class ThreadDemo2 {
    public static void main(String[] args) throws Exception {
        for (int i = 1; i <= 5; i++) {
            System.out.println("输出:" + i);
            if(i == 3) {
                // 进入休眠(毫秒)
                Thread.sleep(3000);
            }
        }
    }
}

线程安全问题

在这里插入图片描述
在这里插入图片描述

package com.mochu.d3_ThreadSecurity;

public class Account {
    private String cardId;
    private double money;

    public Account() {
    }

    public Account(String cardId, double money) {
        this.cardId = cardId;
        this.money = money;
    }

    public String getCardId() {
        return cardId;
    }

    public void setCardId(String cardId) {
        this.cardId = cardId;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    public void drawMoney(double money){
        String name = Thread.currentThread().getName();
        if(this.money >= money) {
            System.out.println(name + "取钱\r\n金额:" + money);
            this.money -= money;
            System.out.println(name + "取钱后剩余:" + this.money);
        }else {
            System.out.println(name + "取钱,余额不足");
        }
    }
}
package com.mochu.d3_ThreadSecurity;

public class DrawThread extends Thread{
    // 接收账户对象
    private Account acc;
    public DrawThread(Account acc, String name) {
        super(name);
        this.acc = acc;
    }

    @Override
    public void run() {
        acc.drawMoney(100000);
    }
}
package com.mochu.d3_ThreadSecurity;

public class ThreadSecurityDemo {
    public static void main(String[] args) {
        Account acc = new Account("ICBC-1111", 100000);

        // 创建两个线程对象
        new DrawThread(acc, "小明").start();
        new DrawThread(acc, "小红").start();
    }
}

在这里插入图片描述

线程同步、同步代码块、同步方法、同步锁

在这里插入图片描述
在这里插入图片描述

同步代码块

在这里插入图片描述

public void drawMoney(double money){
        String name = Thread.currentThread().getName();
        // 同步代码块
        synchronized ("mochu7") {
            if(this.money >= money) {
                System.out.println(name + "取钱\r\n金额:" + money);
                this.money -= money;
                System.out.println(name + "取钱后剩余:" + this.money);
            }else {
                System.out.println(name + "取钱,余额不足");
            }
        }
    }

在这里插入图片描述
在这里插入图片描述

同步方法

在这里插入图片描述

     public synchronized void drawMoney(double money){
        String name = Thread.currentThread().getName();
            if(this.money >= money) {
                System.out.println(name + "取钱\r\n金额:" + money);
                this.money -= money;
                System.out.println(name + "取钱后剩余:" + this.money);
            }else {
                System.out.println(name + "取钱,余额不足");
        }
    }

在这里插入图片描述

Lock锁

在这里插入图片描述

private final Lock lock = new ReentrantLock();

public synchronized void drawMoney(double money){
        String name = Thread.currentThread().getName();
        lock.lock(); // 上锁
        try {
            if(this.money >= money) {
                System.out.println(name + "取钱\r\n金额:" + money);
                this.money -= money;
                System.out.println(name + "取钱后剩余:" + this.money);
            }else {
                System.out.println(name + "取钱,余额不足");
            }
        } finally {
            lock.unlock(); // 无论什么异常情况,都会解锁
        }
    }

线程通信

在这里插入图片描述
在这里插入图片描述

package com.mochu.d5_ThreadCommunication;

public class ThreadCommunicationDemo {
    public static void main(String[] args) {
        Account acc = new Account("ICBC-1122", 0);
        new DrawThread(acc, "小明").start();
        new DrawThread(acc, "小红").start();

        new DepositThread(acc, "亲爹").start();
        new DepositThread(acc, "干爹").start();
        new DepositThread(acc, "岳父").start();
    }
}
package com.mochu.d5_ThreadCommunication;

public class DrawThread extends Thread{
    // 接收账户对象
    private Account acc;
    public DrawThread(Account acc, String name) {
        super(name);
        this.acc = acc;
    }

    @Override
    public void run() {
        while(true) {
            acc.drawMoney(100000);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
package com.mochu.d5_ThreadCommunication;

public class DepositThread extends Thread{
    // 接收账户对象
    private Account acc;
    public DepositThread(Account acc, String name) {
        super(name);
        this.acc = acc;
    }

    @Override
    public void run() {
        while(true) {
            acc.depositMoney(100000);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
package com.mochu.d5_ThreadCommunication;

public class Account {
    private String cardId;
    private double money;

    public Account() {
    }

    public Account(String cardId, double money) {
        this.cardId = cardId;
        this.money = money;
    }

    public String getCardId() {
        return cardId;
    }

    public void setCardId(String cardId) {
        this.cardId = cardId;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    public synchronized void drawMoney(double money){
        try {
            String name = Thread.currentThread().getName();
            if(this.money >= money) {
                System.out.println(name + "取钱\r\n金额:" + money);
                this.money -= money;
                System.out.println(name + "取钱后剩余:" + this.money);
                this.notifyAll();
                this.wait();
            }else {
                this.notifyAll(); // 唤醒所有线程
                this.wait(); // 锁对象,让当前线程进入等待
                System.out.println(name + "取钱,余额不足");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public synchronized void depositMoney(double money) {
        try {
            String name = Thread.currentThread().getName();
            if(this.money == 0) {
                this.money += money;
                System.out.println(name + "存款:" + money + "余额:" + this.money);
                this.notifyAll(); // 唤醒所有线程
                this.wait(); // 锁对象,让当前线程进入等待
            }else {
                this.notifyAll(); // 唤醒所有线程
                this.wait(); // 锁对象,让当前线程进入等待
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

线程池概述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

线程池处理Runnable、Callable任务

在这里插入图片描述
在这里插入图片描述

package com.mochu.d8_ThreadPool;

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 1; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + "输出:" + i);
        }
    }
}
package com.mochu.d8_ThreadPool;

import java.util.concurrent.*;

public class ThreadPoolDemo {
    public static void main(String[] args) {
        // 定义线程池对象
        ExecutorService pool = new ThreadPoolExecutor(3, 5, 5, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

        Runnable target = new MyRunnable();
        pool.execute(target);
        pool.execute(target);
        pool.execute(target);

        // 立即关闭,即使任务没有完成
        pool.shutdownNow();
    }
}

Executors的工具类构建线程池对象

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

定时器

在这里插入图片描述
在这里插入图片描述


package com.mochu.d9_time;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TimeDemo {
    public static void main(String[] args) {
        // 创建Time对象
        Timer timer = new Timer(); // 定时器本身就是单线程
        // 调用方法,处理定时任务
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行AAA一次" + new Date());
//                try {
//                    Thread.sleep(3000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
            }
        }, 0, 2000);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行BBB一次" + new Date());
                // System.out.println(10 / 0); // 当中间某个任务出现异常,整个定时器都会挂掉
            }
        }, 0, 2000);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行CCC一次" + new Date());
            }
        }, 0, 2000);
    }
}

在这里插入图片描述

package com.mochu.d9_time;

import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class TimerDemo02 {
    public static void main(String[] args) {
        // 创建ScheduledExecutorService线程池,做定时器
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行输出:AAA " + new Date());
                try {
                    Thread.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, 0, 2, TimeUnit.SECONDS);

        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行输出:BBB" + new Date());
                System.out.println(10 / 0);
            }
        }, 0, 2, TimeUnit.SECONDS);

        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "执行输出:CCC" + new Date());
            }
        }, 0, 2, TimeUnit.SECONDS);
    }
}

线程并发、并行、线程生命周期的6种状态

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

网络通信三要素:IP及其类InetAddress、端口、协议

在这里插入图片描述

package com.mochu.d1_InetAddressDemo01;

import java.net.InetAddress;

public class InetAddressDemo {
    public static void main(String[] args) throws Exception {
        // 获取本机地址对象
        InetAddress ip1 = InetAddress.getLocalHost();
        System.out.println(ip1);
        System.out.println(ip1.getHostName());
        System.out.println(ip1.getHostAddress());

        // 获取域名IP对象
        InetAddress ip2 = InetAddress.getByName("www.baidu.com");
        System.out.println(ip2);
        System.out.println(ip2.getHostName());
        System.out.println(ip2.getHostAddress());

        // 判断是否互通,单位毫秒
        System.out.println(ip2.isReachable(5000));
    }
}

UDP快速入门、多发多收消息、广播、组播

在这里插入图片描述
在这里插入图片描述

package com.mochu.d2_udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class ClientDemo {
    public static void main(String[] args) throws Exception {
        System.out.println("=======客户端启动=======");
        // 创建UDP发送端对象
        DatagramSocket socket = new DatagramSocket();

        // 创建一个数据包对象封装数据
        byte[] buffer = "mochu7: Hello World".getBytes();
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getLocalHost(), 8888);

        // 发送数据
        socket.send(packet);

        socket.close();
    }
}
package com.mochu.d2_udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ServerDemo {
    public static void main(String[] args) throws Exception{
        System.out.println("=======服务端启动=======");
        // 创建服务端(接收端)对象
        DatagramSocket socket = new DatagramSocket(8888);

        // 创建一个数据包对象接收数据
        byte[] buffer = new byte[1024 * 64];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        // 接收数据
        socket.receive(packet);

        // 取出数据
        int len = packet.getLength();
        String rs = new String(buffer,0, len);
        System.out.println("收到了:" + rs);

        System.out.println("对方IP:" + packet.getSocketAddress().toString());
        System.out.println("对方端口:" + packet.getPort());

        socket.close();
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d2_udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class ClientDemo {
    public static void main(String[] args) throws Exception {
        System.out.println("=======客户端启动=======");
        // 创建UDP发送端对象
        DatagramSocket socket = new DatagramSocket();
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请输入:");
            String msg = sc.nextLine();
            if("exit".equals(msg)) {
                System.out.println("退出成功");
                socket.close();
                break;
            }
            // 创建一个数据包对象封装数据
            byte[] buffer = msg.getBytes();
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getLocalHost(), 8888);
            // 发送数据
            socket.send(packet);
        }
    }
}
package com.mochu.d2_udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ServerDemo {
    public static void main(String[] args) throws Exception{
        System.out.println("=======服务端启动=======");
        // 创建服务端(接收端)对象
        DatagramSocket socket = new DatagramSocket(8888);

        // 创建一个数据包对象接收数据
        byte[] buffer = new byte[1024 * 64];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        while (true) {
            // 接收数据
            socket.receive(packet);
            // 取出数据
            int len = packet.getLength();
            String rs = new String(buffer,0, len);
            System.out.println("收到了:" + rs);
            System.out.println("对方IP:" + packet.getSocketAddress().toString());
            System.out.println("对方端口:" + packet.getPort());
        }
    }
}

在这里插入图片描述

UDP的接收端为什么可以接收很多发送端的消息?

  • 接收端只负责接收数据包,无所谓是哪个发送端的数据包

在这里插入图片描述
在这里插入图片描述
客户端:DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("255.255.255.255"), 9999);
服务端:DatagramSocket socket = new DatagramSocket(9999);

在这里插入图片描述
客户端:DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("224.0.1.1"), 9999);

服务端:

        // 创建服务端(接收端)对象
        MulticastSocket socket = new MulticastSocket(9999);

        // 把当前客户端加入组播组当中
        // socket.joinGroup(InetAddress.getByName("224.0.1.1")); // jdk14过时了
        socket.joinGroup(new InetSocketAddress(InetAddress.getByName("224.0.1.1"), 9999), NetworkInterface.getByInetAddress(InetAddress.getLocalHost()));

TCP通信快速入门

在Java中只要是使用java.net.Socket类实现通信,底层即是使用了TCP协议

在这里插入图片描述
在这里插入图片描述

package com.mochu.d3_Socket;

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

public class ServerDemo {
    public static void main(String[] args) throws Exception {
        try {
            System.out.println("=======服务端启动=======");
            // 注册端口
            ServerSocket serverSocket = new ServerSocket(7777);
            // 调用accpet方法,等待客户端的Socket连接请求,建立Socket通信管道
            Socket socket = serverSocket.accept();
            // 从Socket管道中得到一个字节输入流
            InputStream is = socket.getInputStream();
            // 把字节流包装成成缓冲字节输入流进行消息接收
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            String msg;
            while((msg = br.readLine()) != null) {
                System.out.println(socket.getRemoteSocketAddress() + ": " + msg);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

package com.mochu.d3_Socket;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;

public class ClientDemo {
    public static void main(String[] args) {
        try {
            System.out.println("=======客户端启动=======");
            // 创建Socket通信管道,请求有服务端的链接
            Socket socket = new Socket("127.0.0.1", 7777);

            // 从Socket通信管道中得到一个字节输出流
            OutputStream os = socket.getOutputStream();

            // 把低级的字节流包装成打印流
            PrintStream ps = new PrintStream(os);

            // 发送消息
            ps.println("TCP链接申请");
            ps.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

在这里插入图片描述
在这里插入图片描述

TCP通信实现、多发多收消息、实现同时接收多个客户端

在这里插入图片描述

package com.mochu.d3_Socket;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class ClientDemo {
    public static void main(String[] args) {
        try {
            System.out.println("=======客户端启动=======");
            // 创建Socket通信管道,请求有服务端的链接
            Socket socket = new Socket("127.0.0.1", 7777);
            // 从Socket通信管道中得到一个字节输出流
            OutputStream os = socket.getOutputStream();
            // 把低级的字节流包装成打印流
            PrintStream ps = new PrintStream(os);
            // 发送消息
            Scanner sc = new Scanner(System.in);
            while(true) {
                System.out.println("请说:");
                String msg = sc.nextLine();
                ps.println(msg);
                ps.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
package com.mochu.d3_Socket;

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

public class ServerDemo {
    public static void main(String[] args) throws Exception {
        try {
            System.out.println("=======服务端启动=======");
            // 注册端口
            ServerSocket serverSocket = new ServerSocket(7777);
            // 调用accpet方法,等待客户端的Socket连接请求,建立Socket通信管道
            Socket socket = serverSocket.accept();
            // 从Socket管道中得到一个字节输入流
            InputStream is = socket.getInputStream();
            // 把字节流包装成成缓冲字节输入流进行消息接收
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            String msg;
            while((msg = br.readLine()) != null) {
                System.out.println(socket.getRemoteSocketAddress() + ": " + msg);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

在这里插入图片描述

实现服务端可以同时处理多个客户端消息

package com.mochu.d3_Socket;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class ClientDemo {
    public static void main(String[] args) {
        try {
            System.out.println("=======客户端启动=======");
            // 创建Socket通信管道,请求有服务端的链接
            Socket socket = new Socket("127.0.0.1", 7777);
            // 从Socket通信管道中得到一个字节输出流
            OutputStream os = socket.getOutputStream();
            // 把低级的字节流包装成打印流
            PrintStream ps = new PrintStream(os);
            // 发送消息
            Scanner sc = new Scanner(System.in);
            while(true) {
                System.out.println("请说:");
                String msg = sc.nextLine();
                ps.println(msg);
                ps.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

package com.mochu.d3_Socket;

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

public class ServerDemo {
    public static void main(String[] args) throws Exception {
        try {
            System.out.println("=======服务端启动=======");
            // 注册端口
            ServerSocket serverSocket = new ServerSocket(7777);
            while (true) {
                // 调用accpet方法,等待客户端的Socket连接请求,建立Socket通信管道
                Socket socket = serverSocket.accept();
                System.out.println(socket.getRemoteSocketAddress() + "上线了");
                // 每接收到一个客户端的Socket管道,交给一个独立的子线程负责读取消息
                new ServerReaderThread(socket).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

package com.mochu.d3_Socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class ServerReaderThread extends Thread{
    private Socket socket;

    public ServerReaderThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            // 从Socket管道中得到一个字节输入流
            InputStream is = socket.getInputStream();
            // 把字节流包装成成缓冲字节输入流进行消息接收
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            String msg;
            while((msg = br.readLine()) != null) {
                System.out.println(socket.getRemoteSocketAddress() + ": " + msg);
            }
        } catch (Exception e) {
            System.out.println(socket.getRemoteSocketAddress() + "下线了");
        }
    }
}

在这里插入图片描述

TCP通信模型:线程池优化

在这里插入图片描述

package com.mochu.d3_Socket;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class ClientDemo {
    public static void main(String[] args) {
        try {
            System.out.println("=======客户端启动=======");
            // 创建Socket通信管道,请求有服务端的链接
            Socket socket = new Socket("127.0.0.1", 6666);
            // 从Socket通信管道中得到一个字节输出流
            OutputStream os = socket.getOutputStream();
            // 把低级的字节流包装成打印流
            PrintStream ps = new PrintStream(os);
            // 发送消息
            Scanner sc = new Scanner(System.in);
            while(true) {
                System.out.println("请说:");
                String msg = sc.nextLine();
                ps.println(msg);
                ps.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

package com.mochu.d3_Socket;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;

/**
 * 实现服务端可以同时处理多个客户端的消息
 */
public class ServerDemo {
    // 使用静态变量记住一个线程池对象
    private static ExecutorService pool = new ThreadPoolExecutor(3, 5, 6, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

    public static void main(String[] args) throws Exception {
        try {
            System.out.println("=======服务端启动=======");
            // 注册端口
            ServerSocket serverSocket = new ServerSocket(6666);
            while (true) {
                // 调用accpet方法,等待客户端的Socket连接请求,建立Socket通信管道
                Socket socket = serverSocket.accept();
                System.out.println(socket.getRemoteSocketAddress() + "上线了");
                Runnable target = new ServerReaderRunnable(socket);
                pool.execute(target);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

package com.mochu.d3_Socket;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class ServerReaderRunnable implements Runnable{
    private Socket socket;
    public ServerReaderRunnable(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            // 从Socket管道中得到一个字节输入流
            InputStream is = socket.getInputStream();
            // 把字节流包装成成缓冲字节输入流进行消息接收
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            String msg;
            while((msg = br.readLine()) != null) {
                System.out.println(socket.getRemoteSocketAddress() + ": " + msg);
            }
        } catch (Exception e) {
            System.out.println(socket.getRemoteSocketAddress() + "下线了");
        }
    }
}

在这里插入图片描述

TCP实战案例:即时通信、BS架构模拟

在这里插入图片描述
在这里插入图片描述

package com.mochu.d3_Socket;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class ClientDemo {
    public static void main(String[] args) {
        try {
            System.out.println("=======客户端启动=======");
            // 创建Socket通信管道,请求有服务端的链接
            Socket socket = new Socket("127.0.0.1", 9999);
            // 创建一个独立的线程专门负责这个客户端的读消息(服务端随时可能转发消息过来)
            new ClientReaderThread(socket).start();
            // 从Socket通信管道中得到一个字节输出流
            OutputStream os = socket.getOutputStream();
            // 把低级的字节流包装成打印流
            PrintStream ps = new PrintStream(os);
            // 发送消息
            Scanner sc = new Scanner(System.in);
            while(true) {
                System.out.println("请说:");
                String msg = sc.nextLine();
                ps.println(msg);
                ps.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

package com.mochu.d3_Socket;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class ClientReaderThread extends Thread{
    private Socket socket;
    public ClientReaderThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            // 从Socket管道中得到一个字节输入流
            InputStream is = socket.getInputStream();
            // 把字节流包装成成缓冲字节输入流进行消息接收
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            String msg;
            while((msg = br.readLine()) != null) {
                System.out.println(socket.getRemoteSocketAddress() + ": " + msg);
            }
        } catch (Exception e) {
            System.out.println(socket.getRemoteSocketAddress() + "下线了");
        }
    }
}

package com.mochu.d3_Socket;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 实现服务端可以同时处理多个客户端的消息
 */
public class ServerDemo {
    // 定义一个静态的List集合存储当前全部在线的socket管道
    public static List<Socket> allOnlineSockets = new ArrayList<>();

    public static void main(String[] args) throws Exception {
        try {
            System.out.println("=======服务端启动=======");
            // 注册端口
            ServerSocket serverSocket = new ServerSocket(9999);
            while (true) {
                // 调用accpet方法,等待客户端的Socket连接请求,建立Socket通信管道
                Socket socket = serverSocket.accept();
                System.out.println(socket.getRemoteSocketAddress() + "上线了");
                allOnlineSockets.add(socket); // 上线完成
                // 创建一个线程来单独处理这个socket管道
                new ServerReaderThread(socket).start();

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

    }
}

package com.mochu.d3_Socket;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

public class ServerReaderThread extends Thread{
    private Socket socket;
    public ServerReaderThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            // 从Socket管道中得到一个字节输入流
            InputStream is = socket.getInputStream();
            // 把字节流包装成成缓冲字节输入流进行消息接收
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            String msg;
            while((msg = br.readLine()) != null) {
                System.out.println(socket.getRemoteSocketAddress() + ": " + msg);
                // 把这个消息进行端口转发给全部客户端socket管道
                sendMsgToAll(msg);
            }
        } catch (Exception e) {
            System.out.println(socket.getRemoteSocketAddress() + "下线了");
            ServerDemo.allOnlineSockets.remove(socket);
        }
    }

    private void sendMsgToAll(String msg) throws Exception {
        for (Socket allOnlineSocket : ServerDemo.allOnlineSockets) {
            PrintStream ps = new PrintStream(allOnlineSocket.getOutputStream());
            ps.println(msg);
            ps.flush();
        }
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

BS架构模拟

在这里插入图片描述

package com.mochu.d4_BS;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;

public class BrowseServerDemo {
    // 使用静态变量记住一个线程池对象
    private static ExecutorService pool = new ThreadPoolExecutor(3, 5, 6, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
    public static void main(String[] args) throws Exception {
        try {
            System.out.println("=======服务端启动=======");
            // 注册端口
            ServerSocket serverSocket = new ServerSocket(8080);
            while (true) {
                // 调用accpet方法,等待客户端的Socket连接请求,建立Socket通信管道
                Socket socket = serverSocket.accept();
                pool.execute(new ServerReaderRunnable(socket));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
package com.mochu.d4_BS;

import java.io.PrintStream;
import java.net.Socket;

public class ServerReaderRunnable implements Runnable{
    private Socket socket;
    public ServerReaderRunnable(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            // 浏览器已经与本线程建立乐socket管道
            // 响应消息给浏览器显示
            PrintStream ps = new PrintStream(socket.getOutputStream());
            // 必须响应HTTP格式数据
            ps.println("HTTP1.1 200 OK");
            ps.println("Content-Type: text/html;charset=UTF-8");
            ps.println();
            ps.println("<title>mochu7 page</title>");
            ps.println("<h1>欢迎来到mochu7 page</h1>");
            ps.println("Hello, I'm mochu7777");
            ps.close();
        }catch (Exception e) {
            System.out.println(socket.getRemoteSocketAddress() + "下线了");
        }
    }
}

在这里插入图片描述

单元测试:Junit框架

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d1_JUnit;

public class UserService {
    public String loginName(String loginName, String passWord) {
        if("admin".equals(loginName) && "123456".equals(passWord)) {
            return "登陆成功";
        }else {
            return "用户名或密码错误";
        }
    }

    public void selectName() {
        System.out.println(10/0);
        System.out.println("查询全部用户名成功");
    }
}

package com.mochu.d1_JUnit;

import org.junit.Assert;
import org.junit.Test;

public class TestUserService {
    /**
     * 测试方法
     */
    @Test
    public void testLoginName() {
        UserService userService = new UserService();
        String rs = userService.loginName("admin", "123456");

        // 进行预期结果的正确性测试:断言
        Assert.assertEquals("您的登录功能可能出现了bug", "登陆成功", rs);
    }

    @Test
    public void testSelectName(){
        UserService userService = new UserService();
        userService.selectName();
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d1_JUnit;

import org.junit.*;

public class TestUserService {
    @Before
    public void before() {
        System.out.println("=======brfore=======");
    }

    @After
    public void after() {
        System.out.println("=======after=======");
    }

    @BeforeClass
    public static void beforeClass() {
        System.out.println("=======BeforeClass=======");
    }

    @AfterClass
    public static void afterClass() {
        System.out.println("=======AfterClass=======");
    }

    @Test
    public void testLoginName() {
        UserService userService = new UserService();
        String rs = userService.loginName("admin", "123456");

        // 进行预期结果的正确性测试:断言
        Assert.assertEquals("您的登录功能可能出现了bug", "登陆成功", rs);
    }

    @Test
    public void testSelectName(){
        UserService userService = new UserService();
        userService.selectName();
    }
}

在这里插入图片描述
在这里插入图片描述

反射概述、获取Class类对象

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d2_Reflect;

public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        // 调用Class类中的一个静态方法:forName
        Class c = Class.forName("com.mochu.d2_Reflect.Student");
        System.out.println(c);

        // 通过类名.class
        Class c1 = Student.class;
        System.out.println(c1);

        // 通过对象.getClass() 获取
        Student stu = new Student();
        Class c2 = stu.getClass();
        System.out.println(c2);
    }
}

在这里插入图片描述
在这里插入图片描述

反射获取Constructor、Field、Method对象

在这里插入图片描述
在这里插入图片描述

package com.mochu.d3_Reflect_Constructor;

import org.junit.Test;

import java.lang.reflect.Constructor;

public class TestStudent {
    @Test
    public void getContructors() {
        // 获取类对象
        Class c = Student.class;
        // 获取类中的构造器,只能获取公开的构造器
        Constructor[] constructors = c.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
        }
    }

    @Test
    public void getDeclareConstructors() {
        // 获取类对象
        Class c = Student.class;
        // 获取类中的所有构造器
        Constructor[] constructors = c.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
        }
    }

    @Test
    public void getConstructor() throws Exception {
        // 获取类对象
        Class c = Student.class;
        // 获取类中的某一个构造器,只能拿public
        Constructor constructor = c.getConstructor();
        System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
    }

    @Test
    public void getDeclareConstructor() throws Exception {
        // 获取类对象
        Class c = Student.class;
        // 获取类中的任何一个构造器
        Constructor constructor = c.getDeclaredConstructor();
        System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());

        Constructor constructor1 = c.getDeclaredConstructor(String.class, int.class);
        System.out.println(constructor1.getName() + "===>" + constructor1.getParameterCount());
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d3_Reflect_Constructor;

import org.junit.Test;

import java.lang.reflect.Constructor;

public class TestStudent {
    @Test
    public void getDeclareConstructor() throws Exception {
        // 获取类对象
        Class c = Student.class;
        // 获取类中的任何一个构造器
        Constructor constructor = c.getDeclaredConstructor();
        System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());

        // 如果遇到了私有的构造器,可以暴力反射
        constructor.setAccessible(true);
        Student s = (Student) constructor.newInstance();
        System.out.println(s);

        Constructor constructor1 = c.getDeclaredConstructor(String.class, int.class);
        System.out.println(constructor1.getName() + "===>" + constructor1.getParameterCount());
        Student s1 = (Student) constructor1.newInstance("mochu7", 22);
        System.out.println(s1);
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d4_Reflect_Field;

import org.junit.Test;

import java.lang.reflect.Field;

public class FieldDemo {
    @Test
    public void getDeclareedFields() {
        // 创建class对象
        Class c = Student.class;
        // 获取全部成员变量
        Field[] fileds = c.getDeclaredFields();
        for (Field filed : fileds) {
            System.out.println(filed.getName() + " ===> " + filed.getType());
        }
    }

    @Test
    public void getDeclareedField() throws Exception {
        // 创建class对象
        Class c = Student.class;
        // 根据名称定位某个成员变量
        Field filed = c.getDeclaredField("name");
        // System.out.println(filed.getName() + " ==> " + filed.getType());
        // 成员变量暴力赋值
        filed.setAccessible(true);
        Student s = new Student();
        filed.set(s, "mochu7");
        System.out.println(s);
        String name = (String) filed.get(s);
        System.out.println(name);
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d5_Reflect_Method;

public class Dog {
    private String name;

    public Dog(){

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Dog(String name) {
        this.name = name;
    }

    public void run() {
        System.out.println("Dog running....");
    }

    private void eat() {
        System.out.println("Dog eating...");
    }

    private String eat(String name) {
        System.out.println("Dog eat " + name);
        return "funny eat";
    }

    public static void inAddr() {
        System.out.println("Singal dog~ Singal dog~");
    }
}
package com.mochu.d5_Reflect_Method;

import org.junit.Test;

import java.lang.reflect.Method;

public class MethodDemo {
    @Test
    public void getDeclearedMethods() {
        Class c = Dog.class;
        Method[] methods = c.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method.getName() + " ==> " + method.getReturnType() + " ==> " + method.getParameterCount());
        }
    }

    @Test
    public void getDeclearedMethod() throws Exception {
        Class c = Dog.class;
        Method method = c.getDeclaredMethod("eat");
        Method method2 = c.getDeclaredMethod("eat", String.class);
        // 触发方法执行
        method.setAccessible(true);
        Dog d = new Dog();
        method.invoke(d);

        method2.setAccessible(true);
        method2.invoke(d, "bone");
    }
}

在这里插入图片描述
在这里插入图片描述

反射的作用:绕过编译阶段,做企业级通用框架

在这里插入图片描述

package com.mochu.d6_Reflect_Genericity;

import java.lang.reflect.Method;
import java.util.ArrayList;

public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        // 反射实现泛型擦除,加入其它类型的数据
        ArrayList<String> list1 = new ArrayList<>();
        ArrayList<Integer> list2 = new ArrayList<>();

        System.out.println(list1.getClass());
        System.out.println(list2.getClass());

        System.out.println(list1.getClass() == list2.getClass());

        System.out.println("----------------------------");
        ArrayList<String> list3 = new ArrayList<>();
        list3.add("mochu7");
        list3.add("Slevin");
        Class c = list3.getClass();
        Method add = c.getDeclaredMethod("add", Object.class);
        boolean rs = (boolean) add.invoke(list3, 77);
        System.out.println(rs);
        System.out.println(list3);
        // 突破泛型约束的另一种方法
        ArrayList list4 = list3;
        list4.add(127);
        list4.add(false);
        System.out.println(list3);
    }
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

package com.mochu.d7_Reflect_Framework;

/**
 * 提供一个通用框架,支持保存所有对象信息
 */
public class ReflectDemo {
    public static void main(String[] args) throws Exception{
        Student s = new Student();
        s.setName("mochu7");
        s.setClassName("21345");
        s.setAge(18);
        s.setHobby("睡觉");
        s.setSex('男');
        MybatisUtil.save(s);

        Teacher t = new Teacher();
        t.setName("Slevin");
        t.setSex('男');
        t.setSalary(10000.0);
        MybatisUtil.save(t);
    }
}
package com.mochu.d7_Reflect_Framework;

import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;

public class MybatisUtil {
    /**
     * 保存任意类对象
     * @param obj
     */
    public static void save(Object obj) throws Exception {
        try(PrintStream ps = new PrintStream(new FileOutputStream("JUnit-Reflect-Annotation-Proxy-App/src/data.txt", true));) {
            // 读取这个类的全部成员变量,使用反射
            Class c = obj.getClass();
            ps.println("===============" + c.getSimpleName() + "===============");
            Field[] fields = c.getDeclaredFields();
            for (Field field : fields) {
                String name = field.getName();
                // 提取本成员变量在obj对象中的值
                field.setAccessible(true);
                String value = field.get(obj) + "";
                ps.println(name + "=" + value);
            }
        } catch (Exception e) {
            e.printStackTrace();
            }
        }
    }

在这里插入图片描述

注解概述、自定义注解、元注解、注解解释

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d8_Annotaion;

import org.junit.Test;

import java.lang.reflect.Method;
import java.util.Arrays;

public class AnnoationDemo {
    @Test
    public void parseClass() throws Exception {
        Class c = BookStore.class;
        Method m = c.getDeclaredMethod("test");
        if(m.isAnnotationPresent(Book.class)) {
            // 获取该注解对象
            Book book = (Book) m.getDeclaredAnnotation(Book.class);
            System.out.println(book.value());
            System.out.println(book.price());
            System.out.println(Arrays.toString(book.author()));
        }
    }
}
package com.mochu.d8_Annotaion;


@Book(value = "《中国哲学史》", price = 45.9, author = {"test", "test1"})
public class BookStore {
    @Book(value = "《认知驱动》", price = 24.5, author = {"a1", "a2"})
    public void test() {

    }
}
package com.mochu.d8_Annotaion;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Book {
    String value();
    double price() default 100;
    String[] author();
}

在这里插入图片描述

注解的应用:模拟JUnit框架

在这里插入图片描述

package com.mochu.d8_Annotaion;

import java.lang.reflect.Method;

public class AnnoationDemo {
    @MyTest
    public void test1() {
        System.out.println("===test1===");
    }

    public void test2() {
        System.out.println("===test2===");
    }
    @MyTest
    public void test3(){
        System.out.println("===test3===");
    }

    public static void main(String[] args) throws Exception {
        AnnoationDemo a1 = new AnnoationDemo();
        Class c = AnnoationDemo.class;
        Method[] methods = c.getDeclaredMethods();
        for (Method method : methods) {
            if(method.isAnnotationPresent(MyTest.class)){
                method.invoke(a1);
            }
        }
    }
}
package com.mochu.d8_Annotaion;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
}

在这里插入图片描述

动态代理

代理主要是对对象的行为额外做一些辅助操作

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d9_Proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Objects;

public class StarAgent {
    public static Skill getProxy(Star obj) {
//        newProxyInstance(ClassLoader loader,
//                Class<?>[] interfaces,
//                InvocationHandler h) {
//            Objects.requireNonNull(h);
        return (Skill) Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(), new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("触发代理对象");
                        Object rs = method.invoke(obj, args);
                        return rs;
                    }
                });
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d10_Proxy2;

public class Test {
    public static void main(String[] args) {
        UserService userService = ProxyUtil.getProxy(new UserServiceImpl());
        System.out.println(userService.login("admin", "123456"));
        userService.deleteUsers();
        userService.selectUsers();
        userService.deleteById(1024);
    }
}
package com.mochu.d10_Proxy2;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyUtil {
    public static <T>  T getProxy(T obj) {
        return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        long startTime = System.currentTimeMillis();
                        Object rs = method.invoke(obj, args);
                        long endTime = System.currentTimeMillis();
                        System.out.println(method.getName() + "方法耗时:" + (endTime - startTime) / 1000.0);
                        return rs;
                    }
                });
    }
}
package com.mochu.d10_Proxy2;

public class UserServiceImpl implements UserService{
    @Override
    public String login(String loginName, String passWord) {
        String rs = "用户名或者密码错误";
        if("admin".equals(loginName) && "123456".equals(passWord)) {
            rs = "登录成功";
        }
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rs;
    }

    @Override
    public void deleteUsers() {
        try {
            System.out.println("正在删除用户中.......");
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public String selectUsers() {
        String rs = "正在查询10000个用户";
        try {
            Thread.sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rs;
    }

    @Override
    public void deleteById(int id) {
        try {
            System.out.println("根据用户身份证号" + id + ",删除了他");
            Thread.sleep(1200);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
package com.mochu.d10_Proxy2;

public interface UserService {
    String login(String loginName, String passWord);
    void deleteUsers();
    String selectUsers();
    void deleteById(int id);
}

在这里插入图片描述

XML、XML创建

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

XML文档约束

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

XML文件解析技术:Dom4j

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.mochu.d1_dom4j;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.io.InputStream;

public class Dom4jDemo {
    @Test
    public void parseXMLDdata() throws Exception {
        // 创建一个Dom4j的解析器对象
        SAXReader saxReader = new SAXReader();
        InputStream is = Dom4jDemo.class.getResourceAsStream("/data.xml");
        Document document = saxReader.read(is);
        Element root = document.getRootElement();
        System.out.println(root.getName());
    }
}

在这里插入图片描述

package com.mochu.d1_dom4j;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;

public class Dom4jDemo {
    @Test
    public void parseXMLDdata() throws Exception {
        // 创建一个Dom4j的解析器对象
        SAXReader saxReader = new SAXReader();
        InputStream is = Dom4jDemo.class.getResourceAsStream("/data.xml");
        Document document = saxReader.read(is);
        Element root = document.getRootElement();
        System.out.println(root.getName());

        // 获取根元素下的全部子元素
        List<Element> sonEles = root.elements();
        for (Element sonEle : sonEles) {
            System.out.println(sonEle.getName());
        }

        // 获取某个子元素
        Element nameEle = root.element("name");
        System.out.println(nameEle.getName());

        // 获取某个子元素对象
        System.out.println(nameEle.getText());

        // 获取属性值
        Attribute idAttr = nameEle.attribute("id");
        System.out.println(idAttr.getName() + " => " + idAttr.getValue());
        System.out.println(nameEle.attributeValue("id"));
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d1_dom4j;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;

public class Dom4jDemo {
    @Test
    public void parseXMLDdata() throws Exception {
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(Dom4jDemo.class.getResourceAsStream("/data.xml"));
        Element root = document.getRootElement();
        List<Element> contactEles = root.elements("contact");
        List<Contact> contacts = new ArrayList<>();
        for (Element contactEle : contactEles) {
            Contact contact = new Contact();
            contact.setId(Integer.valueOf(contactEle.attributeValue("id")));
            contact.setName(contactEle.elementTextTrim("name"));
            contact.setGender(contactEle.elementTextTrim("gender").charAt(0));
            contact.setMail(contactEle.elementTextTrim("mail"));
            contacts.add(contact);
        }
        for (Contact contact : contacts) {
            System.out.println(contact);
        }
    }
}

在这里插入图片描述

XML文件的数据检索技术:XPath

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

package com.mochu.d2_Xpath;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;

import java.util.List;


public class XpathDemo {
    // 绝对路径
    @Test
    public void parse01() throws Exception{
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/data.xml"));
        List<Node> nameNodes = document.selectNodes("/contactList/contact/name");
        for (Node nameNode : nameNodes) {
            Element nameEle = (Element) nameNode;
            System.out.println(nameEle.getTextTrim());
        }
    }

    // 相对路径
    @Test
    public void parse02() throws Exception{
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/data.xml"));
        Element root = document.getRootElement();
        List<Node> nameNodes = root.selectNodes("./contact/name");
        for (Node nameNode : nameNodes) {
            Element nameEle = (Element) nameNode;
            System.out.println(nameEle.getTextTrim());
        }
    }

    // 全文检索
    @Test
    public void parse03() throws Exception{
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/data.xml"));
        List<Node> nameNodes = document.selectNodes("//name");
        for (Node nameNode : nameNodes) {
            Element nameEle = (Element) nameNode;
            System.out.println(nameEle.getTextTrim());
        }
    }

    // 属性查找
    @Test
    public void parse04() throws Exception{
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/data.xml"));
        List<Node> nodes = document.selectNodes("//@id");
        for (Node node : nodes) {
            Attribute attr = (Attribute) node;
            System.out.println(attr.getName() + " => " + attr.getValue());
        }
    }
}

补充知识:工厂模式、装饰模式

在这里插入图片描述
在这里插入图片描述

package com.mochu.d3_FactoryPattern;

public class Factory {
    // 定义一个方法,创建对象返回
    public static Computer createComputer(String info) {
        switch (info){
            case "Mac":
                Computer c = new Mac();
                c.setName("Mac15 Pro");
                c.setPrice(15999);
                return c;
            case "Alien":
                Computer c1 = new Alien();
                c1.setName("Alien X17");
                c1.setPrice(27999);
                return c1;
            default:
                return null;
        }
    }
}
package com.mochu.d3_FactoryPattern;

public class FactoryDemo {
    public static void main(String[] args) {
        Computer c = Factory.createComputer("Alien");
        c.start();

        Computer c1 = Factory.createComputer("Mac");
        c1.start();
    }
}

在这里插入图片描述
在这里插入图片描述

package com.mochu.d4_decorator_pattern;

public abstract class InputStream {
    public abstract int read();
    public abstract int read(byte[] buffer);
}
package com.mochu.d4_decorator_pattern;

import java.util.Arrays;

public class FileInputStream extends InputStream{
    @Override
    public int read() {
        System.out.println("读取了一个字节a");
        return 97;
    }

    @Override
    public int read(byte[] buffer) {
        buffer[0] = 97;
        buffer[1] = 98;
        buffer[2] = 99;
        System.out.println("读取了一个字节数组:" + Arrays.toString(buffer));
        return 0;
    }
}
package com.mochu.d4_decorator_pattern;

// 装饰类,扩展原始类的功能
public class BufferedInputStream extends InputStream{
    private InputStream is;

    public BufferedInputStream (InputStream is) {
        this.is = is;
    }

    @Override
    public int read() {
        System.out.println("提供8KB缓冲区,提高数据性能");
        return is.read();
    }

    @Override
    public int read(byte[] buffer) {
        System.out.println("提供8KB缓冲区,提高数据性能");
        return is.read(buffer);
    }
}
package com.mochu.d4_decorator_pattern;

public class DecoratorPattern {
    public static void main(String[] args) {
        InputStream is = new BufferedInputStream(new FileInputStream());
        System.out.println(is.read());
        System.out.println(is.read(new byte[3]));
    }
}

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

末初mochu7

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值