JavaSE基础学习(四)—Java核心类库(下)

目录

思维导图快速预览全文内容

在这里插入图片描述

一、异常机制(重点)

1、基本概念

  • Java语言中指程序执行中发生的不正常情况
  • java.lang.Throwable类是Error类和Exception类的父类
  • Error类主要描述Java虚拟机无法解决的严重错误,通常无法编码解决,如:JVM挂掉等
  • Exception类主要描述因编程错误或偶然外在因素导致的轻微错误,可以编码解决,如:0为除数等
  • 注意:
    当程序执行过程中发生异常,但是没有手动处理时,Java虚拟机会采用默认方式进行处理,默认处理方式为:打印异常名称、异常发生的原因、异常发生的位置,然后终止程序

2、异常分类

  • java.lang.Exception 所有异常的超类
    • RuntimeException 运行时异常,也叫非检测性异常
      •  ArithmeticException 算术异常
      •  ArrayIndexOutOfBoundsException 数组下标越界异常
      •  NullPointerException 空指针异常
      •  ClassCastException 类型转换异常
      •  NumberFormatException 数字格式化异常
    • IOException和其他异常 其他异常,也叫检测异常,就是在编译阶段可以被编译器检测出来的异常
      在这里插入图片描述

3、异常的避免

  • 以后开发中尽量使用if条件判断避免异常的发生
  • 但是过多的if条件导致程序代码臃肿,可读性差

4、异常的捕获

  • 语法格式
try{
	编写可能发生异常的代码;
}catch(异常类型 引用变量名){
	编写针对异常的处理代码;
}finally{
	无论是否异常都执行的代码;
}
  • 注意事项
    1. 当需要编写多个catch分支时,小类型应该写在大类型前面
    2. 懒人写法:catch(Exception ex){}
    3. finally通常用于进行善后处理,比如:关闭已经打开的文件等
  • 笔试考点
    分析下方代码返回结果
public class FinallyExamTest {
    public static void main(String[] args) {
        System.out.println(test());  //2
    }
    public static int test(){
        try{
            String[] arr = new String[5];
            String s = arr[5];
            return 0;
        }catch(ArrayIndexOutOfBoundsException a){
            a.printStackTrace();
            return 1;
        }finally {  //在catch中代码执行完后,方法结束即return之前会执行finally代码块,
                    // 相当于finally代码块是在catch块的return之前(有return时)/catch块的最后一行代码执行完后(无return时),增加了一个finally代码块
                    // 总之方法退出之前一定会执行finally块,不会直接在catch中退出方法而不执行finally
            return 2;
        }
    }
}

5、异常的抛出

  • 基本概念
    某些情况下,异常不能处理或不便于处理时,可以将异常抛出给方法的调用者,这种方法叫做异常的抛出。
    当方法执行出现异常,则底层生成一个异常类对象抛出,此时异常类代码后续的代码就不再执行。

  • 语法格式

访问权限 返回值类型 方法名称(形参列表) throws 异常类型1,异常类型2...{
	方法体;
}
  • 方法重写原则
    1. 方法名相同,参数列表及返回值类型相同,从jdk1.5开始支持返回子类型
    2. 方法访问权限不能变小,可以相同或不变
    3. 方法不能抛出更大异常
  • 注意
    1. 子类重写方法不能抛出更大的异常
    2. 不能抛出平级但不一样的异常
    3. 但可以抛出一样的异常,更小的异常或者不抛出异常
    4. 不建议在main中抛出异常
  • 经验分享
    1. 若父类中被重写的方法没有抛出异常时,则子类重写的方法只能进行异常捕获处理
    2. 若一个方法内又以递进方式调用了好几个其他方法,则建议这些方法内可以使用抛出的方法处理到最后一层进行捕获方式处理(如下方代码)
public class ExceptionThrowTest {
    public static void main(String[] args) {
        test1();
    }
    public static void test1(){
        //test1中递进调用了test2,test3,show方法,这些方法可以都抛出异常,在最后一层test1中进行异常捕获统一处理
        try {
            test2();
        } catch (IOException e) {
            System.out.println("文件不存在!");
            e.printStackTrace();
        }
    }
    public static void test2() throws IOException {
        test3();
    }
    public static void test3() throws IOException {
        show();
    }
    public static void show() throws IOException {
        FileInputStream fis = new FileInputStream("D:a.txt");
        fis.close();
    }
}

6、自定义异常

  • 基本概念
    当需要在程序中表达年龄不合理的情况时,因为Java官方没有提供这种针对性的异常,此时可以采用自定义异常实现
  • 实现流程
  1. 自定义异常类xxxException继承自Exception类或其子类;
  2. 自定义异常类提供俩个版本构造方法,一个是无参构造,一个是字符串作为参数的构造方法。
  • 自定义异常的产生
    示例:
throw new 自定义异常类型(实参);
//如:
throw new AgeException("年龄不合理!");
  • 注意
    Java采用的异常处理机制,是将异常处理的程序代码集中在一起,与正常的程序代码分,使得程序简洁,优雅并易于维护。

二、File类(重点)

1、 基本概念

java.io.File类主要用于描述文件或者目录的抽象表示信息,可以获取文件或目录的特征信息,如文件大小等

2、常用方法

方法声明功能介绍
File​(String pathname)根据参数指定路径名构造对象
File​(File parent, String child)根据参数指定的抽象父路径和子路径信息构造对象
File​(String parent, String child)根据参数指定的父路径和子路径信息构造对
boolean exists()测试此抽象路径名表示的文件或目录是否存在
String getName()获取文件或目录的名称
long length()返回此抽象路径名表示的文件的长度
long lastModified()获取文件的最后修改时间
String getAbsolutePath()获取文件的绝对路径字符串
boolean delete()删除此抽象路径名表示的文件或目录
boolean createNewFile()当且仅当具有该抽象路径名的文件尚不存在时,以原子方式创建一个新的空文件
boolean mkdir()创建以此抽象路径名命名的目录
boolean mkdirs()创建多级目录
File[] listFiles()获取目录下的所有文件
boolean isFile()判断是否为文件
boolean isDirectory()判断是否为目录
File[] listFiles​(FileFilter filter)获取目录下满足筛选器的所有文件及目录

3、案例题目

遍历获取目录及子目录下的所有符合要求文件并打印

import java.io.File;
import java.io.FileFilter;

public class FileTest2 {
    public static void main(String[] args) {
        File f = new File("E:/test");
        cal(f);
    }
    public static void cal(File file){
        File[] files = file.listFiles();
        for (File f:files) {
            if(f.isFile() && f.getName().endsWith(".zip")){
                System.out.println(f);
            }
            if(f.isDirectory()){
                cal(f);
            }
        }

    }
}

三、IO流和RandomAccessFile类

1、概念

  • IO即Input和Ouput的简写,输入输出的意思
  • IO流是指读数据时像流水一样 从一端读到另一端,因此得名“流”

2、基本分类

  • 按照读写数据基本单位不同,分为:字符流 、字节流
    1. 字节流:主要指以字节为单位进行数据读写,可以读写任意类型的文件
    2. 字符流:主要指以字符(2个字节)为单位进行数据读写,只能读写文本文件
  • 按照读写数据方向不同,分为:输入流、输出流
    1. 输入流:指从文件中读取数据内容输入到程序中,也就是读文件
    2. 输出流:指将程序中数据内容输出到文件中,也就是写文件
  • 按照流的角色不同,分为:节点流、处理流
    1. 节点流:直接和输入输出源对接的流
    2. 处理流:指需要建立在节点流基础之上的流

3、体系结构

在这里插入图片描述
IO流框架结构
在这里插入图片描述

4、相关流的详解

4.1 FileWriter类(重点)

  • 基本概念
    java.io.FileWriter类主要用于将文本内容写入到文本文件中
  • 常用方法
方法声明功能介绍
FileWriter​(String fileName)根据参数指定的文件名构造对象
FileWriter​(String fileName, boolean append)以追加的方式根据参数指定的文件名构造对象
void write​(int c)写入单个字符
void write​(char[] cbuf, int off, int len)将指定字符数组中指定偏移量off开始的len个字符写入文件输出流
write​(char[] cbuf)将字符数组写入到文件输出流中
void flush()刷新流
void close()关闭流对象并释放有关资源

4.2 FileReader类(重点)

  • 基本概念
    java.io.FileReader类主要用于从文本文件读取文本数据内容
  • 常用方法
方法声明功能介绍
FileReader​(String fileName)根据参数指定的文件名构造对象
int read()读取单个字符的数据并返回,返回-1表示读取到末尾
int read​(char[] cbuf, int offset, int length)从输入流中将最多len个字符的数据读入到一个字符数组中,返回读取的字符个数,返回-1表示读取到末尾
int read​(char[] cbuf)将cbuf.length个字符读入到字符数组中,返回读取到的字符个数。返回-1表示读取到末尾
void close()关闭流并释放有关资源

4.3 FileOutputStream类(重点)

  • 基本概念
    java.io.FileOutputStream类主要用于将图像之类的原始字节流写入到输出流中
  • 常用方法
方法声明功能介绍
FileOutputStream​(String name)根据参数指定文件名构造对象
FileOutputStream​(String name, boolean append)以追加的方式根据参数指定的文件名构造对象
void write​(int b)将指定字节写入此文件输出流
void write​(byte[] b, int off, int len)将指定字符数组中指定偏移量off开始的len个字符写入文件输出流
void write​(byte[] b)将b.length个字节,从指定字节数组中写入此文件输出流中
void flush()刷新此输出流并强制写出任何缓冲区的输出字节
void close()关闭流对象并释放有关资源

4.4 FileInputStream类(重点)

  • 基本概念
    java.io.FileInputStream类主要用于从输入流中以字节流的方式读取图像数据等
  • 常用方法
方法声明功能介绍
FileInputStream​(String name)根据参数指定文件名构造对象
int read()读取单个字节的数据并返回,返回-1表示读取到末尾
int read​(byte[] b, int off, int len)从输入流中将最多len个字节的数据读入到一个字节数组中,返回读取的字节个数,返回-1表示读取到末尾
int read​(byte[] b)将b.length个字节读入到字节数组中,返回读取到的字节个数。返回-1表示读取到末尾
void close()关闭流对象并释放有关资源
int available()获取输入流所关联文件大小

4.5 BufferOutputStream类(重点)

  • 基本概念
    java.io.BufferedOutputStream类用于描述缓冲输出流,此时不同为写入的每个字节调用底层系统
  • 常用方法
方法声明功能介绍
BufferedOutputStream​(OutputStream out)根据参数指定引用构造对象
BufferedOutputStream​(OutputStream out, int size)根据参数指定的引用和缓冲区大小来构造对象
void write​(int b)写入单个字节
void write​(byte[] b, int off, int len)写入字节数组中的一部分数据
void write​(byte[] b)写入字节数组
void flush()刷新流
void close()关闭流释放有关资源

4.6 BufferedInputStream类(重点)

  • 基本概念
    java.io.BufferedInputStream类用于描述缓冲输入流
  • 常用方法
方法声明功能介绍
BufferedInputStream​(InputStream in)根据参数指定引用构造对象
BufferedInputStream​(InputStream in, int size)据参数指定的引用和缓冲区大小来构造对象
int read()读取单个字节
int read​(byte[] b, int off, int len)读取len个字节
int read​(byte[] b)读取b.length个字节
void close()关闭流对象并释放有关资源

4.7 BufferedWriter(重点)

  • 基本概念
    java.io.BufferedWriter主要用于写入单个字符,字符数组,以及字符串到输出流中
  • 常用方法
方法声明功能介绍
BufferedWriter​(Writer out)根据参数指定引用构造对象
BufferedWriter​(Writer out, int sz)根据参数指定的引用和缓冲区大小来构造对象
void write​(int c)写入单个字符到输出流中
void write​(char[] cbuf, int off, int len)将字符数组的部分内容写入输出流中
void write​(char[] cbuf)整个字符数组写入到输出流中
void write​(String s, int off, int len)参数s中下标从off开始的len个字符写入到输出流
void write​(String str)写入字符串到输出流
void newLine()
void flush()刷新流
void close()关闭流并释放资源

4.8 BufferedReader类(重点)

  • 基本概念
    java.io.BufferedReader类用于从输入流中读取单个字符、字符数组、字符串
  • 常用方法
方法声明功能介绍
BufferedReader​(Reader in)根据参数指定引用构造对象
BufferedReader​(Reader in, int sz)根据参数指定的引用和缓冲区大小来构造对象
int read()从输入流读取字符,读取到末尾则返回-1,否则返回读取内容
int read​(char[] cbuf, int off, int len)读取字符数组len个字符的内容,读取到末尾返回-1,否则返回实际读取的字符个数
int read​(char[] cbuf)从输入流中读取整个字符数组,返回读取的字符个数
String readLine()读取一行字符串并返回,返回null表示读取到末尾
void close()关闭流,释放资源

4.9 PrintStream类

  • 基本概念

  • 常用方法

方法声明功能介绍
PrintStream​(OutputStream out)根据参数指定引用构造对象
PrintStream​(OutputStream out, boolean autoFlush)根据参数指定引用及是否自动刷新构造对象
void print​(String s)打印参数指定的字符内容
void println​(String x)打印字符串后并终止该行
void flush()刷新流
void close()关闭流,释放资源

4.10 PrintWriter类

  • 基本概念
    java.io.PrintWriter类主要用于将对象的格式化形式打印到文本输出流
  • 常用方法
方法声明功能介绍
PrintStream​(OutputStream out)根据参数指定引用构造对象
PrintStream​(OutputStream out, boolean autoFlush)根据参数指定引用及是否自动刷新构造对象
void print​(String s)打印参数指定的字符内容
void println​(String x)打印字符串后并终止该行
void flush()刷新流
void close()关闭流,释放资源

4.11 OutPutStreamWriter

  • 基本概念
    实现字符输出流向字节输出流的转换
  • 常用方法
    参考官方API

4.12 InputStreamReader

  • 基本概念
    字符输入流向字节输入流的转换
  • 常用方法
    参考官方API

4.13 字符编码

  • 编码表的由来
    为方便计算机可以识别各个国家的文字,需要各个国家的文字用数字描述并建立对应的关系表,此表即为编码表
  • 常见的编码表
    ASCII:美国标准信息交换码
    ISO-8859-1:拉丁码表,欧洲码表
    GB2312:中文编码表初版
    GBK:中文编码表升级版,融合更多中文字符号
    Unicode:国际标准码,融合目前人类使用的所有字符,每个字符分配了唯一的字符码,所有文字都用2个字节16位二进制表示
  • 编码发展
    • UTF标准出现,UTF-8是每次8个位传输数据,UTF-16是每次16个位传输数据
    • Unicode只是定义了一个庞大的全球通用字符集,并为每一个字符规定了唯一的编号,具体存储成什么样的字节流,取决于字符编码方案,推荐的Unicode编码是UTF-8和UTF-16
    • UTF-8,变长的编码方式,可用1-4个字节表示一个字符
      参考:超级详细的字符集与编码方式解释与发展历程

4.14 DataOutputStream(了解)

  • 基本概念
    主要用于将基本数据类型写入输出流中
  • 常用方法
    参考官方API

4.15 DataInputStream(了解)

  • 基本概念
    从输入流中读取基本数据类型
  • 常用方法
    参考官方API

4.16 ObjectOutputStream(重点)

  • 基本概念
    • 用于将一个对象的所有内容整体写入到输出流中
    • 写入的对象必须实现Serialization接口(启动序列化功能)
    • 序列化:将对象的状态信息转换为可以存储或传输的形式,比如:把一个Java对象写入到硬盘或者传输到网路上面的其它计算机
  • 常用方法
    ObjectOutputStream​(OutputStream out)、
    void writeObject​(Object obj)、
    void close()
  • transient关键字
    用于修饰成员变量,表示该成员变量不参与序列化操作,修饰后的成员变量不会被转换为存储或者传输的形式
  • 序列化版本号
    用于验证版本一致性。
    JVM会把传来的字节流中的serialVersionUID与本地相应实体类的版本号比较,一致则会进行反序列化,否则会报异常(InvalidCastException)

4.17 ObjecctInputStream(重点)

  • 基本概念
    • 从输入流中将对象一次性读取出来
    • 反序列化:将二进制数据转换回原对象
  • 常用方法
    ObjectInputStream​(InputStream in)、
    Object readObject()、
    void close()

5、RandomAccessFile类

  • 基本概念
    支持随机访问文件的读写操作

  • 常用方法
    RandomAccessFile​(String name, String mode)、
    int read()、
    void seek​(long pos)、
    void write​(int b)、
    void close()
    更详细关于RandomAccessFile介绍


四、多线程

1、基本概念


1.1 程序和进程的概念

  • 程序:数据结构 + 算法,主要指存放在硬盘上的可执行文件
  • 进程:主要指运行在内存中可执行文件
  • 目前主流操作系统都支持多进程,但是新建一个进程会消耗CPU和内存空间等系统资源,因此进程的数量比较有限

1.2 线程的概念

  • 为了解决进程不能创建太多,但是又需要同时执行多个任务的问题,提出线程。
  • 线程是进程内部的程序流,也就是说:操作系统支持多进程,每个进程支持多线程
  • 线程是轻量级的,同一个进程的多个线程会共享所在进程的系统资源,因此目前主流开发都采用多线程
  • 多线程采用时间片轮转法保证多个线程的并发执行

2、线程的创建和启动方式


2.1 继承Thread类(重中之重)

方式1:自定义类继承Thread类,并重写run方法;然后创建该类对象调用start方法启动线程
方式2:继承 加 匿名内部类创建和启动线程,参考代码如下:
		new Thread(){
            @Override
            public void run(){
                //重写run方法
            }
        }.start();

2.2 实现Runnable接口(重中之重)

  1. 自定义类实现Runnable接口并实现run方法;然后创建该类对象,作为实参再创建Thread类对象;调用Thread类对象的start方法启动线程(因为start方法是Thread类特有的,Runnable接口没有)
  2. 实现接口 加 匿名内部类创建和启动线程,参考代码如下:
		new Thread(new Runnable(){
            @Override
            public void run() {
                //实现run方法
            }
        }).start();
        
        //Java8开始支持lambda表达式  (形参列表)->{方法体;}
        new Thread(() -> {
            //实现run方法
            }).start();

2.3 实现java.util.concurrent.Callable接口-Java5开始支持(熟悉)

  1. 自定义Callable接口实现类

    (1) 创建自定义接口实现类的对象;
    (2) 用该对象作为参数构造一个FutureTask类的对象;
    (3) 再将FutureTask类对象作为参数构造Thread对象;
    (4) 用Thread对象调用start方法启动线程。

    同时可以通过FutureTask对象的get方法获取到Callable接口自定义实现类的call方法的返回值。
    代码如下:

public class ThreadCallableTest implements Callable {
    public static void main(String[] args) throws Exception {
        FutureTask ft = new FutureTask(new ThreadCallableTest());
        new Thread(ft).start();
        System.out.println("num = " + ft.get());
    }
    @Override
    public Object call() throws Exception {
        System.out.println(Thread.currentThread().getName());
        //计算1-100的和
        int num = 0;
        for(int i = 1; i <= 100; i++){
            num += i;
        }
        return num;
    }
}

补充:关于FutureTask类介绍

  1. 用匿名内部类代替自定义实现类,同上操作构造出最终的Thread对象调用start启动线程。

2.4 线程池方式(熟悉)

  1. java.util.concurrent.Executors工具类
方法功能
static ExecutorService newCachedThreadPool()创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
static ExecutorService newFixedThreadPool​(int nThreads)创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
static ExecutorService newSingleThreadExecutor()创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
static ScheduledExecutorService newScheduledThreadPool​(int corePoolSize)创建一个定长线程池,支持定时及周期性任务执行
		//1、创建一个线程池(创建线程池)
        ExecutorService pool = Executors.newFixedThreadPool(5);
        //2、向线程池提交任务(启动线程)
        pool.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是匿名内部类的run方法");
            }
        });
        //3、关闭线程池
        pool.shutdown();
  1. java.util.concurrent.ExecutorService接口

    该接口的主要实现类是ThreadPoolExecutor,常用方法如下

方法功能
void execute​(Runnable command)执行任务,通常用于执行Runnable
<T> Future<T> submit​(Callable<T> task)执行任务,通常用于执行Callable
void shutdown()关闭线程池
		//1、创建ThreadPoolExecutor子类的对象(创建线程池)
        ThreadPoolExecutor tpool = new ScheduledThreadPoolExecutor(10);
        //2、向线程池提交任务(启动线程)
        tpool.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是匿名内部类的run方法");
            }
        });
        //3、关闭线程池
        tpool.shutdown();

3、线程的声明周期(熟悉)

在这里插入图片描述

  • 新建状态[New]:new线程之后的状态(未运行)
  • 就绪状态[Runnable/Ready]:调用start方法后/阻塞状态解除后的状态(未运行)
  • 运行状态[Running]:线程调度器调用线程后的状态(线程运行)
  • 消亡状态[Terminated]:线程执行完毕后的状态(线程终止)
  • 阻塞状态[Blocked]:线程被阻塞事件中断后的状态,比如sleep

4、线程常用的方法(重点)

方法功能
static void yield()线程离开运行状态,回到就绪状态,让出CPU的执行权,增加其他线程先执行的机会(也有可能让出执行权后CPU调度仍然是该线程抢到执行权,重新被执行)
static void sleep​(long millis)使线程进入阻塞状态,阻塞指定时间后进入就绪状态,如果阻塞时被其他线程打断,会触发InterruptedException
int getPriority()获取线程优先级
void setPriority​(int newPriority)修改线程的优先级,优先级高的线程不一定会先执行,只是获取到时间片的机会更多一些
void join()等待该线程结束
void join​(long millis)等待线程指定毫秒数
boolean isDaemon()用于判断是否为守护线程 Java守护线程的理解和使用场景
void setDaemon​(boolean on)设置线程为守护线程 守护线程设置方式与介绍

5、线程的同步机制(重点)


5.1 基本概念

  • 当多个线程同时访问同一种共享资源时,可能会造成数据不一致问题,需要对线程进行通信与协调,该机制就是同步机制
  • 多线程并发安全问题:多线程并发读取同一个临界资源时
  • 异步操作:多线程各自独立运行
  • 同步操作:多线程串行 操作,按照顺序执行

5.2 解决方案

  • 多线程操作同一个账户时,线程1执行完取款、更新余额的操作,再让线程2执行取款、更新操作
  • 对该段代码来说,从并行改为串行操作

5.3 实现方式

  • synchronized关键字
  • Lock锁

-----主要区别-----
(1)synchronized可以加在方法上,也可以加在特定代码块中,括号中表示需要锁的对象;Lock锁只能锁住代码块
(2)synchronized是由JDK实现的,释放资源;Lock锁必须显式释放锁(unlock()方法)
(3)synchronized是Java中的关键字;Lock是java的一个接口,常用的实现类是ReentrantLock
(4)Lock锁时,Java虚拟机花费较少资源调度线程,性能较好

5.4 静态方法锁定

对静态方法加锁,锁住的是类对象

5.5 注意事项

  • synchronized给代码块加锁时,括号中的锁对象必须是同一个对象,才能起到加锁的作用
  • 同步代码块时,尽量减少同步的范围,提高并发效率

5.6 线程安全类和线程不安全类

  • StringBuffer类线程安全;StringBuilder类线程不安全
  • Vector类线程安全;ArrayList类线程不安全
  • Hashtable类线程安全;HashMap类线程不安全
  • 可以用Collections.synchronizedList()和Collections.synchronizedMap​()将List和Map对象设置为线程安全的对象

5.7 死锁

  • 描述:线程1等待线程2执行完毕,而线程2在等待线程1执行完毕,造成死锁
  • 避免:尽量减少同步的资源;减少同步代码块的嵌套使用

6、Object类常用方法

方法功能
void wait()是线程进入等待状态,直到其他线程调用notify或者notifyAll方法
void wait​(long timeoutMillis)线程进入等待状态,直到等待时间结束,或者有其他线程调用了唤醒方法
void notify()随机唤醒等待的单个线程
void notifyAll()唤醒等待的所有线程

五、网络编程

1、网络编程常识


1.1 七层网络协议

在这里插入图片描述

1.2 相关的协议(笔试题)

  • 协议概念
    计算机在网络通信中的实现通信的一些约定和规则
  • TCP协议
    • 传输控制协议,面向连接,类似于打电话
    • 建立连接 -> 进行通信 -> 断开连接
    • 传输前采用"三次握手"方式
    • 通信的整个过程全程保持连接
    • 保证数据传输的可靠性和有序性
    • 一种全双工的字节流通信方式,可以进行大数据量的传输
    • 传输完需要释放已建立的连接,发送数据的效率较低
  • UDP协议
    • 用户数据报协议,非面向连接,类似写信
    • 通信整个过程中不需要建立连接
    • 不保证数据传输的可靠性和有序性
    • 是一种全双工的数据报通信方式,每个数据报的大小限制在64K以内
    • 发送数据完毕后无需释放,开销小,发送数据的效率较高,速度快

1.3 IP地址(重点)

  • IP地址是互联网的唯一地址标识。32位二进制组成的整数-IPV4;128位二进制组成的整数-IPV6
  • 日常使用点分十进制表示法描述IP地址,将每个字节的二进制转换为一个十进制整数,不同的整数间用小数点隔开

1.4 端口号(重点)

  • IP地址可以定位到某一台设备
  • 端口号可以定位到设备中的某一个进程
  • 端口号本质是16位二进制组成的整数,表示范围:0-65535。其中0-1024已经被操作系统占用
  • 特殊端口熟记:
    HTTP-80、
    FTP-21、
    Oracle-1521、
    Mysql-3306、
    Tomcat-8080
  • IP地址+端口号,组合一起叫套接字:Socket 套接字介绍

2、基于TCP协议编程模型(重点)


2.1 C/S架构

客户向服务器发出请求,服务器接收到请求后做出响应

2.2 编程模型

  • 服务器
    1. 创建ServerSocket类型对象并提供端口号
    2. 调用accep() 方法等待客户端连接请求
    3. 使用输入输出流进行通信
    4. 关闭ServerSocket
  • 客户端
    1. 创建Socket类型对象并提供服务器IP和端口
    2. 使用输入输出流进行通信
    3. 关闭Socket

2.3 相关类和方法

  • ServerSocket类
    • 主要描述服务器套接字信息
    • 常用方法
      ServerSocket​(int port)、
      Socket accept()、
      void close()

3、基于UDP协议的编程模型


3.1 编程模型

  • 接收方
    1. 创建DatagramSocket类型对象并提供端口号
    2. 创建DatagramPacket类型的对象并提供缓冲区
    3. 通过Socket接收数据内容,调用receive方法将数据内容存放到packet对象中
    4. 关闭Socket
  • 发送方
    1. 创建DatagramSocket类型的对象
    2. 创建DatagramPacket类型的对象并提供接收方的通信地址
    3. 通过Socket将packet对象发送出去,send方法
    4. 关闭Socket

3.2 相关类和方法

  • DatagramSocket类
    • 常用方法
      DatagramSocket​(int port)、
      void receive​(DatagramPacket p)、
      void send​(DatagramPacket p)、
      void close()
  • DatagramPacket类
    • 常用方法
      DatagramPacket​(byte[] buf, int length)、
      DatagramPacket​(byte[] buf, int offset, int length, InetAddress address, int port)、
      InetAddress getAddress()、
      int getPort()、
      int getLength()
  • InetAddress类
    • 常用方法
      static InetAddress getLocalHost()、
      static InetAddress getByName​(String host)

4、URL类(熟悉)


4.1 基本概念

  • URL表示统一资源定位器
  • 常见的资源网站www和ftp站点
  • 基本结构:
    协议://主机名:端口号/资源地址
    如:http://10.0.190.32:9000/login.do

4.2 常用方法

URL​(String spec)、
String getProtocol()、
String getHost()、
int getPort()、
String getPath()、
String getFile()、
URLConnection openConnection()

4.3 URLConnection类

  • 基本概念
    该类为抽象类,主要实现类:HttpURLConnection类
  • HttpURLConnection类常用方法
    InputStream getInputStream()、
    void disconnect()

六、反射机制

1、概念

  • 在某些场合下,写代码的时候不确定要创建的对象类型,也不确定要调用什么方法,这些都希望运行时传递的参数来决定,该机制叫动态编程机制,也就是反射机制
  • 简单来说,反射机制就是动态创建对象、动态调用方法
  • 目前主流的框架底层都是采用反射机制实现

2、Class类


2.1 概念

  • Class类的实例可以描述Java中的类和接口,也就是一种数据类型
  • 该类没有构造方法,该类的实例由Java虚拟机和类加载器自动构造完成,本质是加载到内存中的运行时类

2.2 获取Class对象的方式

  • 数据类型.class
  • 引用/对象.getClass()
  • 包装类.TYPE 获取基本数据类型的Class对象
  • Class.forName​(String className) 获取参数指定类型的Class对象
  • ClassLoader类加载器

2.3 常用方法(掌握)

方法功能
static Class<?> forName​(String className)获取参数指定的Class对象并返回
T newInstance()用于创建该Class对象所表示的类的新实例Java9开始已过时,被clazz.getDeclaredConstructor().newInstance()替代

3、 Constructor类


3.1 概念

  • 用于反射机制中获取构造方法信息

3.2 Class类相关常用方法

方法功能
Constructor getConstructor​(Class<?>… parameterTypes)用于获取此Class对象所表示类型中参数指定的公共构造方法(只能获取公共的)
Constructor<?>[] getConstructors()用于获取此Class对象所表示的类型中所有的公共构造方法(只能获取公共的)

3.3 Constructor类常用方法

方法功能
T newInstance​(Object… initargs)使用Constructor类的对象所描述的构造方法来描述Class对象代表类型的新实例
int getModifiers()获取Constructor类描述的构造方法的访问修饰符
String getName()获取Constructor类描述的构造方法的名称
Class<?>[] getParameterTypes()获取Constructor类描述的构造方法所有参数的类型
		//示例:有参方式构造对象
		Class c = Class.forName("com.lagou.test.reflect.User");
        Constructor constructor = c.getConstructor(String.class,int.class);
        Object user = constructor.newInstance("张飞", 99);
        System.out.println(user);

4、Field类


4.1 概念

  • 用于反射机制中获取成员变量信息

4.2 Class类相关常用方法

方法功能
Field getDeclaredField​(String name)获取Class对象表示类中参数指定的成员变量(包含私有)
Field[] getDeclaredFields()获取Class对象表示的类中的所有成员变量(包含私有)

4.3 Field常用方法

方法功能
Object get​(Object obj)获取参数对象中该Filed对象表示的成员变量的数值
void set​(Object obj, Object value)将参数对象中此field对象表示的成员变量的数值修改为value
void setAccessible​(boolean flag)参数为true时,反射对象在使用时应该取消Java语言访问检查
int getModifiers()获取成员变量的访问修饰符
Class<?> getType()获取成员变量数据类型
String getName()获取成员变量的名称
/**
     * 反射机制使用Field类方法示例
     * @throws ClassNotFoundException
     * @throws NoSuchMethodException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws InstantiationException
     * @throws NoSuchFieldException
     */
public static void useFieldByReflect() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        //1、通过反射获取到User类
        Class c = Class.forName("com.lagou.test.reflect.User");
        //2、通过Class类对象获取User类的有参构造方法
        Constructor constructor = c.getConstructor(String.class,int.class);
        //3、通过有参构造器创建User对象
        Object user = constructor.newInstance("张飞", 99);
        //4、通过Class类对象获取User类的名为name的成员变量
        Field name = c.getDeclaredField("name");
        //5、打印成员变量name的权限修饰符
        System.out.println(name.getModifiers());
        //6、打印成员变量name的变量名
        System.out.println(name.getName());
        //7、打印成员变量name的数据类型
        System.out.println(name.getType());
        //由源码可知:获取和修改成员变量数值时有访问检查,需要关闭访问检查才能获取到值,不设置会报异常:IllegalAccessException
        name.setAccessible(true);
        //8、获取成员变量name的数值
        System.out.println("name = " + name.get(user));
        //9、给成员变量name设置新的数值
        name.set(user, "关羽");
        //10、打印成员变量name的新数值
        System.out.println("name = " + name.get(user));
    }

在这里插入图片描述

5、 Method类


5.1 概念

  • 用于反射机制中获取成员方法

5.2 Class类相关常用方法

方法功能
Method getMethod​(String name, Class<?>… parameterTypes)获取该Class对象表示的类中名name,参数为parameterTypes的公共成员方法(只能获取公共的)
Method[] getMethods()获取该Class对象表示的类中所有公共成员方法(只能获取公共的)

5.3 Method类的常用方法

方法功能
Object invoke​(Object obj, Object… args)使用对象obj调用此Method对象所表示的方法,实参传递args
int getModifiers()获取方法的访问修饰符
Class<?> getReturnType()获取方法的返回值类型
String getName()获取方法的名称
Class<?>[] getParameterTypes()获取方法所有参数的类型
Class<?>[] getExceptionTypes()获取方法的异常信息
/**
     * 通过反射使用Method类的常用方法
     * @throws ClassNotFoundException
     * @throws NoSuchMethodException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws InstantiationException
     */
    public static void useMethodByReflect() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //1、反射获取User类的Class对象
        Class c = Class.forName("com.lagou.test.reflect.User");
        //2、通过Class对象获取User类的所有公有成员方法
        Method[] methods = c.getMethods();
        //3、遍历所有公有成员方法
        for (Method m : methods) {
            //3.1、打印每个成员方法的名称
            System.out.println("方法名:" + m.getName());
            //3.2、打印每个成员方法的访问修饰符
            System.out.println("方法修饰符:" + m.getModifiers());
            //3.3、打印每个成员方法的返回值类型
            System.out.println("返回值类型:" + m.getReturnType());
            //3.4、打印每个成员方法的所有参数类型
            Class<?>[] parameterTypes = m.getParameterTypes();
            for (Class pt : parameterTypes) {
                System.out.println("--该方法参数类型:" + pt.getName());
            }

            //3.5、打印每个成员方法的所有异常信息
            Class<?>[] exceptionTypes = m.getExceptionTypes();
            for (Class et : exceptionTypes) {
                System.out.println("-----该方法异常类型:" + et.getName());
            }
            System.out.println("--------------成员方法分隔符----------------");
        }
        //4、通过反射获取其中一个指定公有成员方法
        Method verifyAge = c.getMethod("verifyAge", int.class);
        //5、通过反射调用Class对象表示的User对象的verifyAge方法
        //5.1获取User的无参构造器
        Constructor constructor = c.getConstructor();
        //5.2使用User无参构造器创建一个User对象
        Object user = constructor.newInstance();
        //5.3使用user对象调用verifyAge方法,传参200,验证年龄200是否符合(0-150)的范围
        Object returnValue = verifyAge.invoke(user, 200);
        
        //6、打印verifyAge方法的返回结果
        System.out.println("verifyAge方法的返回值:" + returnValue);
    }

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

6、Class类获取其他信息的方法

方法功能
Package getPackage()获取Class对象表示的类所在包信息
Class<? super T> getSuperclass()获取Class对象表示的类所继承的父类信息
Class<?>[] getInterfaces()获取Class对象表示的类现有的所有接口
Annotation[] getAnnotations()获取Class对象表示的类所有注解信息
Type[] getGenericInterfaces()获取Class对象表示的类所有泛型信息




文章内容输出来源:拉勾教育_大数据开发高新训练营第3期

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

迟到_啦

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值