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

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

文章目录

  • 黑马程序员Java教程学习笔记(六)
    • File概述、File对象创建
    • File类的常用方法
    • 方法递归
    • 非规律化递归问题:文件搜索
    • IO前置内容:字符集
    • IO流分类、文件字节输入流、读取字节数据、避免乱码的方案
    • 文件字节输出流、文件拷贝、释放资源的2种方式
    • 文件字符输入流、文件字符输出流
    • 缓冲流的分类、字节缓冲流使用
    • 字节缓冲流的性能分析
    • 字符缓冲流
    • 代码与文件编码不一致读取乱码问题、转换流
    • 对象序列化、反序列化
    • 打印流、Properties、commons-io框架
    • 线程概述、线程的创建方式
    • 线程常用方法
    • 线程安全问题
    • 线程同步、同步代码块、同步方法、同步锁
    • 线程通信
    • 线程池概述
    • 线程池处理Runnable、Callable任务
    • Executors的工具类构建线程池对象
    • 定时器
    • 线程并发、并行、线程生命周期的6种状态
    • 网络通信三要素:IP及其类InetAddress、端口、协议
    • UDP快速入门、多发多收消息、广播、组播
    • TCP通信快速入门
    • TCP通信实现、多发多收消息、实现同时接收多个客户端
    • TCP通信模型:线程池优化
    • TCP实战案例:即时通信、BS架构模拟
    • 单元测试:Junit框架
    • 反射概述、获取Class类对象
    • 反射获取Constructor、Field、Method对象
    • 反射的作用:绕过编译阶段,做企业级通用框架
    • 注解概述、自定义注解、元注解、注解解释
    • 注解的应用:模拟JUnit框架
    • 动态代理
    • XML、XML创建
    • XML文档约束
    • XML文件解析技术:Dom4j
    • XML文件的数据检索技术:XPath
    • 补充知识:工厂模式、装饰模式


黑马程序员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

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

  • https://dom4j.github.io/
    在这里插入图片描述
    在这里插入图片描述
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

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

  • http://www.java2s.com/Code/Jar/j/Downloadjaxen112jar.htm
    在这里插入图片描述
    在这里插入图片描述

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

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]));
    }
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/5620.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

P1003 [NOIP2011 提高组] 铺地毯

题目描述 为了准备一个独特的颁奖典礼&#xff0c;组织者在会场的一片矩形区域&#xff08;可看做是平面直角坐标系的第一象限&#xff09;铺上一些矩形地毯。一共有 &#xfffd;n 张地毯&#xff0c;编号从 11 到 &#xfffd;n。现在将这些地毯按照编号从小到大的顺序平行于…

C语言试题生成与考试系统的设计与实现

当前&#xff0c;网络教学方兴未艾。网上考试已在其中扮演了重要的角色&#xff0c;传统试卷考试方式有待提高。网络教学已从其规范性、科学性及考试工作组织、管理的统一性&#xff0c;影响到教学质量的好坏。基于此&#xff0c;本系统开发实现了基于B/S模式的c试题生成与考试…

经典毕设项目-博客系统(spring boot、spring mvc、mybatis) gitee开源源码

目录 项目背景 核心技术 项目页面设计 注册页面 登录页面 博客列表页 博客详情页 个人博客列表页 个人博客发布页 个人博客修改页 项目模块与需求分析 AOP 处理模块 用户模块 文章模块 项目创建 实现 AOP 模块 实现登录拦截器 拦截器 拦截注册 实现统一数据…

补充C语言

1.关键字 前言: C90一共有32个关键字,C99比C90多了5个关键字,但主流的编译器对C99关键字支持的不是特别好, 所以后面主要以C90的32个关键字为标准1.1认识auto关键字 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() {int i 0;auto int j 0;retur…

为什么要参加软考?软考如何备考?

软考是指软件工程师职业资格考试&#xff0c;它是由国家人力资源和社会保障部颁发的国家级职业资格证书&#xff0c;是目前我国最具权威性的计算机职业资格证书之一。软考考试内容丰富&#xff0c;包括软件工程、软件测试、软件项目管理、数据库等多个方面&#xff0c;考试难度…

Java分布式事务(七)

文章目录 🔥Seata提供XA模式实现分布式事务_业务说明🔥Seata提供XA模式实现分布式事务_下载启动Seata服务🔥Seata提供XA模式实现分布式事务_搭建聚合父工程构建🔥Seata提供XA模式实现分布式事务_转账功能实现上🔥Seata提供XA模式实现分布式事务_转账功能实现下🔥Se…

Qt-Web混合开发-CEF加载网页简单示例(12)

Qt-Web混合开发-CEF加载网页简单示例&#x1f499;&#x1f353; 文章目录Qt-Web混合开发-CEF加载网页简单示例&#x1f499;&#x1f353;1、概述&#x1f41b;&#x1f986;2、实现效果&#x1f605;&#x1f64f;3、实现功能&#x1f42e;&#x1f434;4、Qt部分关键代码&am…

2023/4/2总结

题解 线段树OR树状数组 - Virtual Judge (vjudge.net) 正如这道题目一样&#xff0c;我的心情也如此。 1.这道题是线段树问题&#xff0c;更改学生值即可&#xff0c;不需要用到懒惰标记。 2.再去按照区间查找即可。&#xff08;多组输入&#xff0c;拿20多次提交换来的&am…

2023大数据开发就业前景怎么样?

大数据开发就业班正在火热招生中。 大数据开发做什么&#xff1f; 大数据开发分两类&#xff0c;编写Hadoop、Spark的应用程序和对大数据处理系统本身进行开发。大数据开发工程师主要负责公司大数据平台的开发和维护、相关工具平台的架构设计与产品开发、网络日志大…

【算法基础】(一)基础算法 --- 位运算

✨个人主页&#xff1a;bit me ✨当前专栏&#xff1a;算法基础 &#x1f525;专栏简介&#xff1a;该专栏主要更新一些基础算法题&#xff0c;有参加蓝桥杯等算法题竞赛或者正在刷题的铁汁们可以关注一下&#xff0c;互相监督打卡学习 &#x1f339; &#x1f339; &#x1f3…

C语言函数大全--d开头的函数

C语言函数大全 本篇介绍C语言函数大全–d开头的函数 1. detectgraph 1.1 函数说明 函数声明函数功能void detectgraph(int *graphdriver, int *graphmode);通过检测硬件确定图形驱动程序和模式 1.2 演示示例 #include <graphics.h> #include <stdlib.h> #incl…

【Java 并发编程】一文读懂线程、协程、守护线程

一文读懂线程、协程、守护线程1. 线程的调度1.1 协同式线程调度1.2 抢占式线程调度1.3 设置线程的优先级2. 线程的实现模型和协程2.1 内核线程实现2.2 用户线程实现2.3 混合实现2.4 Java 线程的实现2.5 协程2.5.1 出现的原因2.5.2 什么是协程2.5.3 Java19 虚拟线程 - 协程的复苏…

Activiti7与Spring、Spring Boot整合开发

Activiti整合Spring 一、Activiti与Spring整合开发 1.1 Activiti与Spring整合的配置 1)、在pom.xml文件引入坐标 如下 <properties><slf4j.version>1.6.6</slf4j.version><log4j.version>1.2.12</log4j.version> </properties> <d…

【源码教程案例】AI绘画与安全在未来主要方向有哪些?

AI绘画在未来有许多潜在的发展方向,以下是一些可能的重点领域 高质量图像生成:随着生成模型的不断改进,未来的AI绘画可能会产生更高质量、更真实的图像,以满足各种应用场景的需求。 个性化创作:AI绘画可以通过用户的个性化偏好和需求来定制艺术作品。这种定制可能包括颜…

【gitlab部署】centos8安装gitlab(搭建属于自己的代码服务器)

这里写目录标题部署篇序言要求检查系统是否安装OpenSSH防火墙问题准备gitlab.rb 配置坑点一忘记root密码重置使用篇gitlab转换成中文git关闭注册入口创建用户部署篇 序言 在团队开发过程中&#xff0c;想要拥有高效的开发效率&#xff0c;选择一个好的代码开发工具是必不可少的…

JUnit5用户手册~并行执行

两种运行模式 SAME_THREAD&#xff1a;默认的&#xff0c;测试方法在同一个线程CONCURRENT&#xff1a;并行执行&#xff0c;除非有资源锁junit-platform.properties配置参数配置所有测试方法都并行 junit.jupiter.execution.parallel.enabled true junit.jupiter.execution.…

Kafka3.0.0版本——生产者分区及分区策略

目录一、生产者分区优点二、生产者发送消息的分区策略2.1、默认的分区器2.2、指定分区(partition)值2.3、没有指明分区(partition)值&#xff0c;但有key 的情况2.4、 既没有分区(partition)值&#xff0c;又没有key 值的情况三、指定分区(partition)值的代码示例四、没有指明分…

vscode折叠展开快捷键

1.折叠所有代码 (按住ctrl 分别点击k和0) ctrlk,ctrl0 2.展开所有代码 (按住ctrl 分别点击k和j) ctrlk,ctrlj 3. 折叠鼠标竖线所在位置的节点以及当前节点下的子节点&#xff08;递归折叠&#xff09; ctrlk,ctrl[ 4. 展开鼠标竖线所在位置的节点以及当前节点下的子节点&#…

OpenFeign 源码解读:动态代理+负载均衡实现

OpenFeign使用EnableFeignClients开启服务&#xff0c;该注解标有Import(FeignClientsRegistrar.class)&#xff0c;该ImportBeanDefinitionRegistrar会利用扫描路径的方式扫描java文件中带有的FeignClient(...)的接口&#xff0c;关于这种扫描注解的方式&#xff0c;我仿照写了…

软件测试 - 测试用例常见面试题

1.测试用例的要素测试用例是为了实施测试而向被测试的系统提供的一组集合, 这组集合包含 : 测试环境, 操作步骤, 测试数据, 预期结果等要素.例如 : 在 B 站输入框输入一个空格, 检查结果测试用例标题 : 输入框输入空格测试环境 : Windows 系统, 谷歌浏览器-版本 111.0.5563.65&…