JavaSE2

发布时间:2024年01月20日

一、数组

1.API

API(Application Programming Interface应用程序接口)是一些预先定义的接口。

2.数组概述

  • 数组是用来存储同一类型若干数据的容器
  • 数组是引用类型
  • 数组里面的数据叫元素
  • 数组的长度是固定的,一旦声明就不可变
  • 数组每个容器在内存中连续的存储(每个容器的地址是连续的),则使用下标定位元素
  • 下标是整数,且从0开始

3.数组基础语法

声明
数据类型[] 数组名; 

初始化
内存初始化
   数据类型[] 数组名=new 数据类型[长度];
 元素初始化
   简写方式1:数据类型[] 数组名=new 数据类型[]{元素列表}
   简写方式2:数据类型[] 数组名={元素列表}(但是只能在声明的时候使用)
   
数组元素的默认值
数组内存初始化的时候,数组的容器内的元素是**零值**

* 值类型中的数字类型零值是0
* 值类型中的boolean零值是false
* 引用类型的零值是null

4.数组的操作

数组元素的修改
数组名[下标]=数据;

数组某一个元素的查询(读取)
数组名[下标];

数组全部元素的查询(遍历)
循环下标

5.数组相关问题

数组异常
数组下标超过数组的容量(下标越界)

* java.lang.ArrayIndexOutOfBoundsException

数组对象的属性
length:表示数组的长度

数组特点总结
* 数组长度固定
* 数组有下标


所有接口父类都是object,接口的extends没有继承概念,只是组合概念


数组的内存存储是连续的

6.基本项目开发思路

基本程序开发思路

  • 创建入口包(app)
    • 创建一个main方法
  • 创建实体包(entity,beans)
    • 根据需求封装具体的业务操作类
  • 创建数据包(dao)
    • 负责数据
  • 创建业务包(services)
    • 负责业务逻辑
      • 创建业务逻辑接口
      • 创建业务逻辑接口实现(实现的细节)

基本程序开发各个包之间的依赖关系

业务包依赖数据包

入口包依赖业务包

7.可变长参数

语法

//三点形参
public void fun3(int... a){
}

三点参数为变成参数,只能在参数上出现三点

三点参数的实参可以是数组类型,也可以是非数组类型(使用多个实参逗号隔开)

//可以是数组类型
int[] a3=new int[]{10,20,30,40};
myApp.demoServices.fun3(a3);

//单个非数组类型实参
int a2=2000;
myApp.demoServices.fun3(a2);

//多个非数组类型实参
int a2_1=2000;
int a2_2=3000;
int a2_3=4000;
myApp.demoServices.fun3(a2_1,a2_2,a2_3);

三点参数的形参与非三点参数一起定义的时候,只能放在后面

//todo 三点参数与非三点参数一起
public void fun4(int b,int... a){
}

三点参数的形参个数只能有一个

8.数组算法

[1]冒泡排序

两两交换

冒泡排序是比较基础的排序算法之一,其思想是相邻的元素两两比较,较大的数下沉,较小的数冒起来,这样一趟比较下来,最大()值就会排列在一端。整个过程如同气泡冒起,因此被称作冒泡排序。
//todo 冒泡排序
public void maopao(int[] a) {
    //因为两两比较因此要使用槽长(也就是总长-1),
    int z=a.length - 1;
    for (int i = 0; i <z ; i++) {
        for (int j = 0; j < z-i; j++) {
            if (a[j] > a[j + 1]) {
                int temp = a[j];
                //体现两两交换
                a[j] = a[j + 1];
                a[j + 1] = temp;
            }
        }
    }
}

[2]线性排序/选择排序

每个元素线性与其它元素依次比较

选择排序是一种简单直观的排序算法。它的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,继续放在起始位置,直到未排序元素个数为0//选择排序
public void line(int[] a){
    int z=a.length;
    for(int i=0;i<z;i++){
        for(int j=i+1;j<z;j++){
            if(a[i]>a[j]){
                int temp=a[i];
                a[i]=a[j];
                a[j]=temp;
            }
        }
    }
}

冒泡排序和选择排序程序上的区别

  • 冒泡两两比较,元素都在尾部冒出
  • 选择线性比较,元素都在头部选出

[3]二分查找

  • 前置条件
    • 需要先排好序【升序】
  • 需要头指针(下标)、中指针(下标)、尾指针(下标)
    • 头指针(下标)初始值为0,也就是数组的第一个下标
    • 尾指针(下标)初始值为数组长度-1
    • 中指针(下标)初始值为(头指针+尾指针)/2 【注意这里是取整】
  • 查询规则
    • 待查询的数与中指针相等视为查到
    • 大于
      • 中指针前进(+1)
      • 头指针等于中指针
      • 然后计算中指针【(头指针+尾指针)/2 】
      • 继续查询
    • 小于
      • 中指针后退(-1)
      • 尾指针等于中指针
      • 然后计算中指针【(头指针+尾指针)/2 】
      • 继续查询
    • 继续查询的条件
      • 头指针<=尾头指针
//todo 二分查找
public int binarySearch(int number,int[] a) {
    //二分查找数组先排序
    //先冒泡排序
    maopao(a);
    //返回初始值
    int result=-1;
    //开始初始化三个指针
    //头指针
    int from=0;
    //尾指针
    int end=a.length-1;
    //中指针
    int mid=(from+end)/2;
    //开始查询
    while(from<=end){
        //数据和中指针判断
        if(number==a[mid]){
            //相等情况
            // 找到啦
            result=mid;
            //这里需要注意找到数据后
            //需要退出循环,不然死循环,因为中指针不前进和不后退了
            break;
        }
        else if(number>a[mid]){
            //大于情况
            //中指针前进
            mid+=1;
            //头指针等于中指针位置
            from=mid;
            //从新计算中指针
            mid=(from+end)/2;
        }
        else {
            //小于情况
            //中指针后退
            mid-=1;
            //尾指针等于中指针位置
            end=mid;
            //从新计算中指针
            mid=(from+end)/2;
        }
    }
    //返回查询到的下标
    return result;
}

9.二维数组

  • 一维数组里面的每个元素又是一个数组
  • 二维数组的长度可以任意,换句话说java的二维数组是不规则数组
  • 二维数组初始化
    • 必须先确定一维度数组长度

10.数组工具类

Arrays数组工具类,提供一些静态的各种操作数组的方法

  • 冒泡排序【sort】
  • 二分查找【binarySearch】
  • 数组拷贝【copyOf】

11.数组扩容

二、常用类

1.String字符串类

[1]字符串常量池

内存中有一个区域为字符串常量池,主要是为了优化字符串的

* 创建字符串的时候先搜索字符串常量池是否有字符串序列,如果没有则创建
* 字符串对象使用=运算符的时候实际上是指向字符串常量池
* java提供一个intern()方法类返回一个字符串常量池的引用

[2]String创建方式

  • 字面量创建方法
    • 字面量创建方法中可以使用字符串常量池来达到优化的目的
    • 创建一个新字符串对象时,会先查询字符串常量池是否拥有相等的字符串序列,如果有就不会创建新对象
//字面量创建字符串
String str1="hzj";

* new关键字创建方法
  * 任何时刻都会创建新对象

//使用new关键字创建字符串
String str2=new String("hzj");

[3]intern()方法

该方法返回的字符串序列指向的是字符串常量池中的字符串

[4]equals()方法

比较字符串序列是否相等,不关系内存地址

[5]字符特殊符号+号

  • 字符串+号是连接字符串
  • 字符串对象的字符串序列是不可变的
  • +号连接内部字节码指令规则
    • 链接的字符串都是字面量,则+号实际上省略【字符串常量池中】
    • 链接的字符串有任意一个变量,则立即创建StringBuilder对象,然后使用append方法连接字符串,最后使用toString方法返回新字符串对象【堆中】

[6]字符串总结

  • String类是final
  • String对象可以存在字符串常量池
  • String对象是常量
  • String对象相加,全部字面量相加结果在字符串常量池,否则结果为新字符串在堆
  • String类无法继承 public final class String

2.Date日期类

[1]Date

  • 前日期距离1970-1-1 00:00:00 经过的毫秒数即为日期
  • 存储日期的
  • 提供一个getTime返回日期的毫秒

[2]SimpleDateFormat

日期格式化的返回的是字符串

[3]Calendar

  • 日历负责拆分日期,并提供计算功能
    • Calendar提供了若干字段来表示日期的部分
    • Calendar提供了get方法获取日期的部分
    • Calendar提供set方法类设置一个新的日期
    • Calendar提供add方法增加或者减少日期
  • Calendar提供getTime返回Date对象

新日期架构

机器时间概念–毫秒数

LocalDate日期

LocalTime时间

LocalDateTime日期和时间

3.Math数学类

字段常量

  • 数学API

    提供了数学的支持

  • math提供的全部都是静态方法无需实例化

    math常量PI

    pow方法,求数的几次方

    floor取整,ceil进位,round四舍五入(double类型)

  • 随机数(生成小数)

    Math.random() 大于等于0到小于1.0

    Math.random()*26 0到25

  • 大数字支持

BigDecimal类(小数)

提供基本的大数字构造

提供数字的四则运算方法

add方法加法,

BigInteger类(整数)

4.包装类

[1] 值类型/基本数据类型

byte — Byte

short — Short

int — Integer

long — Long

char — Float

double — Double

boolean — Boolean

每个值类型后面都有一个引用类型支持,叫包装类(引用数据类型)

包装类在实例化的时候可以直接使用值类型(值类型转包装类(隐藏的))

值类型转包装类,目的是为获得包装类方法的支持

包装类的equals方法比较的是字面值

int a=10000;
int b=10000;
//值类型转换包装类,是隐藏手段(这里的隐藏指的是java语法)
Integer a1=10000;
Integer b1=10000;
//值类型比较内容是否相等使用==
System.out.println(a==b);
//引用类型比较内容是否相等不能使用==
System.out.println(a1.equals(b1));
//引用类型使用==比较的是地址
System.out.println(a1==b1);

[2]装箱拆箱

装箱

值类型转换成包装类型

目的:使用包装类的方法,但只能使用equals比较内容,使用==比较内存地址

隐含:实际上是使用了包装类的静态方法valueOf()方法

拆箱

包装类型转换成值类型

目的:不使用包装类的方法,且可以使用==比较内容

隐含:对象方法xx.value() (例如整型拆箱使用intValue())进行拆箱

[3] 包装类的缓存方案

目的:节约创建对象的数量,优化的目的

如果使用new关键字那么必然会创建对象

装箱的时候(调用valueOf)具备优化条件

? 所有整数,创建了数组存了256个数作为缓存区间

? 小数没有缓存区间

? 布尔类型没有缓存区间

三、集合

1. 集合架构

[1] 集合概念

  • 集合也是容器
    • 集合元素是任意数据类型(这也是弱点,泛型可以固定一种类型)
      • 泛型的语法是<数据类型>
    • 集合长度任意
    • 集合元素必须全部都是引用类型
  • 集合在java.util包中
  • Collection接口定义了一些基本的集合操作方法
    • 集合Collection接口继承了Iterable,因此具备迭代能力
    • Collection接口拥有子接口List接口
      • 有下标
      • 可重复
      • 有序

[2] ArrayList

  • 利用数组实现的List集合
    • 数组是固定数据类型
      • 数组是Object数据类型
    • 数组是固定长度
      • 使用数组扩容方案
  • ArrayList特点
    • 拥有下标
    • 集合内容可以重复
    • 集合为有序集合

[3] ArrayList操作

构造

  • 带初始容量参数构造
  • 空构造
  • 带一个集合构造(相当于集合拷贝)

添加

  • add
    • 末尾追加
    • 插入
  • addAll

删除

  • remove
    • 参数为下标
    • 参数为元素
  • removeAll
  • clear

修改

  • set

查询(按条件)

  • get(给定下标)
  • indexOf(给定内容)
  • lastIndexOf(给定内容)

遍历(查询所有)

  • for循环遍历
  • foreach循环
  • 迭代器
  • List迭代器

排序(JDK1.8支持)

  • sort
    • 集合元素类自己实现Comparable接口达到内部排序规则的目的
      • 弱点在于无法修改
      • sort(null)参数为null
    • 创建新类实现Comparator接口达到外部排序规则的目的
      • 弱点,类多(一个规则一个类)
      • sort(外部排序类)
    • 外部排序(Comparator)优先级高于内部排序(Comparable)

面试:微服务主要五个框架,MySQL索引,hash表

[4] 集合基本信息

  • 集合在java.util包中
  • 集合拥有两大接口Collection、Map
  • Collections是集合工具类
  • 集合是容器
  • 集合元素是任意数据类型
  • 集合利用泛型固定数据类型
  • 集合长度任意
  • 集合元素必须全部都是引用类型

2. Collection接口

基础信息

  • Collection接口定义了一些基本的集合操作方法
  • 集合Collection接口继承了Iterable,因此具备迭代能力
  • Collection子接口
    • List接口(可重复,有序)【数组实现、链表实现,序(自然序、升降序)】
    • Set接口(不可重复,无序)【哈希表(数组+链表+红黑),序(无序、升降序、自然序)】
    • Deque接口(可重复,堆栈、队列数据结构)【数组实现、链表实现、(先进先出、先进后出)】

结构图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3. List接口

基本信息

  • 线性数据结构
  • 特点
    • 可重复
    • 有序
  • 子类
    • 数组方案ArrayList(线程不安全)、Vector(线程安全)
    • 链表方案LinkedList

结构图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4. Deque(父接口Queue)

基本信息

  • 双端队列数据结构
  • 同时可以是堆栈数据结构
  • 特点
    • 可重复
    • 有序
  • 子类
    • 数组方案ArrayDeque
    • 链表方案LinkedList
结构图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5. Set接口

基本信息

  • hash、Tree数据结构
  • 特点
    • 不可重复(利用hashCode、equals判定重复)
    • 无序(Tree结构有序)
  • 子类
    • hash方案HaseSet
    • tree方案TreeSet
    • 自然顺序LinkedHashSet

结构图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6. ArrayList子类

基础信息

  • 使用数组扩容改变数组固定长度
    • 初始化容量: 10
    • 扩容: 1.5倍
  • 线程不安全
  • ArrayList优势
    • 自然序
    • 寻址容易(下标)
  • ArrayList弱点
    • 插入和删除困难(下标调整、扩容)
  • ArrayList适合场景
    • 查询

7. ArrayList操作

构造

  • 带初始容量参数构造
  • 空构造
  • 带一个集合构造(相当于集合拷贝)

添加

  • add
    • 末尾追加
    • 插入
  • addAll

删除

  • remove
    • 参数为下标
    • 参数为元素
  • removeAll
  • clear

修改

  • set

查询(按条件)

  • get(给定下标)
  • indexOf(给定内容)
  • lastIndexOf(给定内容)

遍历(查询所有)

  • for循环遍历
  • foreach循环
  • 迭代器
  • List迭代器

排序(JDK1.8支持)

  • sort
    • 集合元素类自己实现Comparable接口达到内部排序规则的目的
      • 弱点在于无法修改
      • sort(null)参数为null
    • 创建新类实现Comparator接口达到外部排序规则的目的
      • 弱点,类多(一个规则一个类)
      • sort(外部排序类)
    • 外部排序(Comparator)优先级高于内部排序(Comparable)

8. Vector子类

基础信息

  • 使用数组扩容改变数组固定长度
    • 初始化容量: 10
    • 扩容: 2倍
  • 线程安全
  • 操作与ArrayList一样

9. LinkedList子类

基础信息

  • 链表实现List、Deque接口
  • LinkedList优势
    • 可以队列
    • 可以堆栈
    • 可以线性
    • 插入和删除容易
  • LinkedList弱点
    • 寻址困难(无下标)
  • LinkedList使用场景
    • 队列
    • 堆栈
    • 增加、删除

10. HastSet子类

基本信息

  • 底层是HashMap
    • 需要hashCode与equals都相等则视为相等
  • 线程不安全
  • HashSet优势
    • 无重复
  • HashSet弱点
    • 无序(遍历顺序不确定)
  • HashSet使用场景
    • 点赞
    • 投票
    • 去重

11. TreeSet子类

基本信息

  • 底层TreeMap
  • Comparator、Comparable接口判定相等实现无重复
  • 排序使用TreeMap的红黑树算法
  • 线程不安全
  • TreeSet优势
    • 无重复
    • 升降序(Comparator、Comparable接口判定排序依据)
  • TreeSet弱点
    • 升降序消耗性能
  • TreeSet使用场景
    • 去重
    • 升降序

12. Map接口

基本信息

  • 键值对
  • 特点
    • 建为Set集合
    • 值为List集合
  • 子类
    • HashMap
    • LinkedHashMap
    • TreeMap
    • ConcurrentHashMap(线程安全)

13. HashMap子类

基本信息

  • 哈希表(数组+链表+红黑树)【结合了数组和链表的优点】数据结构
  • 线程不安全
  • HashMap优点
    • 无序
    • 查询、增、删效率高
  • HashMap弱点
    • 遍历顺序不确定

14. LinkedHashMap子类

基本信息

  • 数组+链表+红黑树数据结构
  • 线程不安全
  • LinkedHashMap优点
    • 自然序
    • 查询效率高
  • LinkedHashMap弱点
    • 效率略低

15. TreeMap子类

基本信息

  • 红黑树数据结构
  • 线程不安全
  • TreeMap优点
    • 升降序(Comparator、Comparable接口判定排序依据)
  • TreeMap弱点
    • 效率略低

四、异常

1.异常的分类

  • Throwable为异常的父类
    • Error表示程序无法处理
    • Exception表示程序可以处理
      • Exception一般异常
      • RuntimeException运行时异常

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.异常的处理流程

  • 一般异常不处理,直接无法编译
  • 运行时异常不出处理,如果不触发异常没事,触发异常程序中断
  • 处理
    • 第一:捕获(try范围)
    • 第二:处理(catch(异常类型)范围)
    • 第三:扫尾(finally范围)(可以不写,但是一旦写出来,必执行)
  • 好处:
    • 程序不会因为异常而中断

3.异常的基本操作

基本的操作(但是太多try)

try {
    //捕获(不一定以引发)
    String str = null;
    System.out.println(str.length());
}
catch (Exception e){
    //处理
    System.out.println("字符串是空的...");
}
try {
    int a=10;
    System.out.println(a/0);
}
catch (Exception e){
    System.out.println("除数不能是0");
}
try {
    int[] b= {1,2,3};
    System.out.println(b[10]);
}
catch (Exception e){
    System.out.println("数组超标啦");
}
System.out.println("今天还可以...........");

多路catch

try {
    //捕获(不一定以引发)
    String str = null;
    System.out.println(str.length());
    int a=10;
    System.out.println(a/0);
    int[] b= {1,2,3};
    System.out.println(b[10]);
}
catch (NullPointerException e){
    //处理空指针
    System.out.println("字符串是空的...");
}
catch (ArithmeticException e){
    //处理除0
    System.out.println("不可除0");
}
catch (ArrayIndexOutOfBoundsException e){
    //处理数组超标
    System.out.println("数组超标");
}
catch (Exception e){
    //处理(兜底)
    System.out.println("反正报错了,也不知道什么错");
}                
System.out.println("今天还可以...........");

finally

try {
    String str = null;
    System.out.println(str.length());
    System.out.println("aaaaaaaaaaaaaaaaa");
    //碰到exit中断,那么finally就不会执行
    //System.exit(0);
    //return关键字一定终止方法
    return;
} catch (Exception e) {
    System.out.println("字符串空啦");
} finally {
    //一般在这里做一些关闭(EasyExcel)
    System.out.println("我是扫尾");
}
System.out.println("开心呀");   

什么时候用try

  • 一般异常
  • 运行时异常
    • 无法判断用户输入的时候
public static void main(String[] args) {
    //输入接收变量
    int i=0;
    //避免JVM编译期认为while死循环,导致while后面代码没法执行
    //boolean b=true;
    //给三次输入机会
    int js=1;
    while (js<=3){
        try {
            //Scanner每次都需要一个新对象
            Scanner scanner=new Scanner(System.in);
            //如果目前没有办法使用if判断那么就使用异常捕获
            i = scanner.nextInt();
            break;
        }
        catch (Exception e){
            System.out.println("请你输入整数");
            js++;
        }
    }
    System.out.println(i);
    System.out.println("程序结束................");
}

4.throws关键字

throws关键字向上抛出异常

  • 向上抛出异常
  • 写在方法上面
  • DAO层向业务层抛,如果业务层不能处理,向控制层抛。
  • 一般都是抛具体的异常
//如果引发异常,我的业务没办法处理
//向上抛出异常,由调用本方法的对象处理
//在方法声明最后使用关键字throws 然后加上异常类型
//throws可以跟多个异常类
//throws可以直接使用Exception完事,但是绝对不提倡
public int fun1() throws NullPointerException, ClassNotFoundException {
    int length = 0;
    String str = null;
    //向上抛运行时异常NullPointerException
    //这里也无法处理,因此向上抛
    length = str.length();
    //调用了向上抛一般异常ClassNotFoundException的forName方法
    //这里也无法处理,因此继续向上抛
    Class.forName("aaaaa");
    return length;
}
//我们在看别人写的方法的时候一定要看是否向上抛了异常
//那么你作为方法的调用者,你需要考虑,是否继续向上抛,还是try处理
public static Class<?> forName(String className)
            throws ClassNotFoundException {
    Class<?> caller = Reflection.getCallerClass();
    return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}

throw关键字构造异常

  • throw一般会联合throws,达到调用方处理异常的目的
  • throw会根据实际情况直接构造一个异常出来
  • catch可以根据异常类型来做不同的处理,因此throw一个异常对象如果不是JAVA提供的,则可以自定义一个异常类
    • 自定义异常操作
      • 继承Exception代表一般异常,必须捕获
      • 继承RuntimeException代表运行时异常,可以不捕获
      • 一定要使用构造方法携参数形式,把异常信息输入进来
//自定义一个30岁异常
public class My30AgeException extends  Exception {
    //使用构造方法输入异常信息
    public My30AgeException(String message) {
        super(message);
    }
}

//自定义一个21岁异常
public class My21AgeException extends  Exception{
    public My21AgeException(String message) {
        super(message);
    }
}

//业务类里面的一个方法
public void fun3(int age) throws My30AgeException, My21AgeException {
    System.out.println("报名");
    if (age >= 30) {
        //构建了一个异常
        throw new My30AgeException("30岁搞架构师");
    }
    else if(age <= 21){
        throw new My21AgeException("21搞学历");
    }
    else{
        System.out.println("上学");
    }
}

//调用业务类的一个代码段
MyServices myServices = new MyServices();
try {
    myServices.fun3(18);
} catch (My30AgeException e) {
    e.printStackTrace();
    System.out.println("进架构师班级");
} catch (My21AgeException e) {
    e.printStackTrace();
    System.out.println("进学历提升班级");
}
System.out.println("程序继续运行...................");

五、IO流

流 指文件内容

输入 input

输出 output

文件内容

文件可以存在硬盘上,那么流即文件的内容在硬盘上

单位

字节(二进制文件)基本单位

字符(文本文件)2字节

方向

源头—>目的地 输出

目的地---->源头 输入

功能

节点流(直接连接源头和目的地的)

过滤流(连接节点的)

JavaIO流的架构

File类

File类代表硬盘中的?件或?件夹

File类直接使?new关键+?件路径实例化对象

File对象指的是?件的属性

File对象基本操作

  • 查看?件的基本属性,例如?件名、??、是?件夹还是?件等

创建?件或?件夹

删除?件或?件夹

判定?件或?件夹是否存在

使?listFiles?法返回??件或??件夹

通常使?递归来获取所有的?件或?件夹

IO流

?件内容

?件可以存在于硬盘上,那么流即?件的内容在硬盘上(流的源在硬盘上)

流的总量(字节数)是固定的

?件可以存在于?络上,那么流即?件的内容在?络上

流的总量(字节数)是不固定的(只有下载完毕后,才真正知道流的总量)

流stream的三个要领(?件内容(即流))

单位

字节(?进制?件)(byte)基本单位

InputStream、OutputStream

字符(?本?件)(char)(等于2字节)

Reader、Writer

?向【Java参照我们的程序】

源头(?件内容)->?的地(我们的程序)(输?)

InputStream、Reader

?的地(我们的程序)->源头(?件内容)(输出)

OutputStream、Writer

功能

节点流(直接连接(源头)和(?的地))

FileReader、FileInputStream、FileOutputStream、FileWriter

功能流(过滤)(连接节点的)

缓存功能

BufferedInputStream、BufferedReader、BufferedOutputStream、 BufferedWriter、

字节流转字符流

InputStreamReader、OutputStreamWriter

有关流的操作【?件的操作】

读取?件内容【字符】

		//字符流读取流程
        String path = "d:\\abc.txt";
        FileReader fileReader = null;
        try {
            fileReader = new FileReader(path);
            //舀水的杯子的大小
            char[] chars = new char[1024 * 1024];
            //read返回的结果如果是-1代表源读完了
            int read = fileReader.read(chars, 0, chars.length);
            //源还有没有流
            //System.out.println("read="+read);
            while (read != -1) {
                String info = new String(chars, 0, read);
                System.out.print(info);
                read = fileReader.read(chars, 0, chars.length);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

写??件内容【字符】

String path = "d:\\abc.txt";
        String info = "(央视财经《经济信息联播》)一位老人清早在路边散步时,\n" +
                "因为突然受到一声气喇叭的惊吓而倒地身亡。家属认为按喇叭的司机存在重大过错,\n
        "随即将相关人员告上了法庭,索赔34万余元。";
        FileWriter fileWriter = null;
        try {
            //第二参数代表是否覆盖,默认覆盖,给true代表追加
            fileWriter = new FileWriter(path, true);
            fileWriter.write(info);
            //输出需要flush()刷新缓存
            fileWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

?件拷?

//拷贝都是用字节流操作
        //源
        String path1 = "d:\\stu.xls";
        //目标
        String path2 = "d:\\stucopy.xls";
        File file1 = new File(path1);
        //文件先创建
        File file2 = new File(path2);
        if (!file2.exists()) {
            //开始创建
            try {
                boolean newFile = file2.createNewFile();
                if (!newFile) {
                    System.out.println("你没空间了");
                    return;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //开始拷贝
        //d:\\stu.xls
        FileInputStream fileInputStream = null;
        //"d:\\stucopy.xls";
        FileOutputStream fileOutputStream = null;
        try {
            //字节输入流创建
            fileInputStream = new FileInputStream(path1);
            //获得流的总量
            //fileInputStream.available();
            //字节输出流创建
            fileOutputStream = new FileOutputStream(path2, false);
            //水瓢,水瓢越循环次数越少
            byte[] bytes = new byte[1024];
            //读取d:\stu.xls的内容到我们程序的水瓢里面(bytes)
            int read = fileInputStream.read(bytes, 0, bytes.length);
            //read返回的不是-1代表没有读完
            while (read != -1) {
                //拷贝,就是这里不System.out.println();
                //把我们程序的水瓢里面(bytes)数据,输出到d:\\stucopy.xls里面
                fileOutputStream.write(bytes, 0, read);
                System.out.println("正在拷贝..................");
                //继续读取d:\stu.xls的内容到我们程序的水瓢里面(bytes)
                read = fileInputStream.read(bytes, 0, bytes.length);
            }
            //输出有缓存支持,所以输出一定要清空缓存
            fileOutputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

缓存功能流【BufferedReader 】

String path = "d:\\abc.txt";
        FileReader fileReader = null;
        BufferedReader bufferedReader = null;
        try {
            fileReader = new FileReader(path);
            //功能流的特点
            //字符缓存读取功能流,就使用它的读一行功能
            bufferedReader = new BufferedReader(fileReader);
            //读一行功能
            String s = bufferedReader.readLine();
           while(s!=null){
				System.out.println(s);
				s = bufferedReader.readLine();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bufferedReader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
	}

缓存功能流【BufferedWriter】

        String path = "d:\\hzj.txt";
        String info = "企业微信-企业在线协同办公文档-免费使用-在线文档";
        FileWriter fileWriter = null;
        BufferedWriter bufferedWriter = null;
        try {
            //fileWriter有缓存,但不能改
            fileWriter = new FileWriter(path, false);
            //可以自定义缓存
            bufferedWriter = new BufferedWriter(fileWriter, 1024 * 100);
            bufferedWriter.write(info);
            //新功能newLine()
            bufferedWriter.newLine();
            bufferedWriter.write(info);
            //清空缓存
            bufferedWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

字节转字符功能流

public class MyApp12 {
            public InputStream fun1() throws IOException {
                String path = "d:\\abc.txt";
                FileInputStream fileInputStream = new FileInputStream(path);
                return fileInputStream;
            }

            public static void main(String[] args) {
                MyApp12 myApp12 = new MyApp12();
                InputStream inputStream = null;
                InputStreamReader inputStreamReader = null;
                BufferedReader bufferedReader = null;
                try {
                    inputStream = myApp12.fun1();
                    //功能流
                    //字节转字符
                    inputStreamReader = new InputStreamReader(inputStream);
                    //功能流读行再来
                    bufferedReader = new BufferedReader(inputStreamReader);
                    String str = bufferedReader.readLine();
                    while (str != null) {
                        System.out.println(str);
                        str = bufferedReader.readLine();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        bufferedReader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

?件拷?(带缓存功能流)

String path = "d:\\YunJing_ins.exe";
        String pathCopy = "d:\\YunJing_insCopy.exe";
        File file = new File(pathCopy);
        if (file.exists()) {
            System.out.println("文件存在..............");
            return;
        }
        try {
            boolean newFile = file.createNewFile();
            if (!newFile) {
                System.out.println("创建新文件失败..............");
                return;
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("创建新文件异常..............");
            return;
        }
        //把字节转换成字符
        //InputStreamReader inputStreamReader=new InputStreamReader();
        //public InputStream fun1(); public Reader fun1();
        //InputStreamReader inputStreamReader=new InputStreamReader();
        FileInputStream fileInputStream = null;
        BufferedInputStream bufferedInputStream = null;
        FileOutputStream fileOutputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            fileInputStream = new FileInputStream(path);
            bufferedInputStream = new BufferedInputStream(fileInputStream, 1024 * 10
                    fileOutputStream = new FileOutputStream(pathCopy);
            bufferedOutputStream = new BufferedOutputStream(fileOutputStream, 1024 *
            byte[] bytes = new byte[1024];
            int read = bufferedInputStream.read(bytes, 0, bytes.length);
            while (read != -1) {
                bufferedOutputStream.write(bytes, 0, read);
                System.out.println("正在拷贝...................");
                read = bufferedInputStream.read(bytes, 0, bytes.length);
            }
            bufferedOutputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                bufferedOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

有关流的操作【对象的操作】【序列化】

把对象的属性值存成?件
? 只有字节
? DataOutputStream、DataInputStream这两个类都是单纯的读取或者获取对象的属性
? ObjectOutputStream、ObjectInputStream这两个是对象整体的读取或获取
? 对象的整体的读取或者获取叫序列化
? 序列化就是把对象(?个)存成?件,然后利?反序列化再吧对象拿出来

DataOutputStream操作

 public class Stu {
            int id;
            String name;
            int age;
            LocalDate localDate;

            public Stu(int id, String name, int age, LocalDate localDate) {
                this.id = id;
                this.name = name;
                this.age = age;
                this.localDate = localDate;
            }

            public Stu() {
            }

            @Override
            public String toString() {
                return "Stu{" +
                        "id=" + id +
                        ", name='" + name + '\'' +
                        ", age=" + age +
                        ", localDate=" + localDate +
                        '}';
            }

            public int getId() {
                return id;
            }

            public void setId(int id) {
                this.id = id;
            }

            public String getName() {
                return name;
            }

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

            public int getAge() {
                return age;
            }

            public void setAge(int age) {
                this.age = age;
            }

            public LocalDate getLocalDate() {
                return localDate;
            }

            public void setLocalDate(LocalDate localDate) {
                this.localDate = localDate;
            }
        }
public class MyApp {
            public static void main(String[] args) {
                Stu stu1 = new Stu();
                stu1.setId(1);
                stu1.setName("hzj");
                stu1.setAge(18);
                stu1.setLocalDate(LocalDate.of(2022, 8, 9));
                System.out.println(stu1);
                String path = "d:\\mystu1.hzj";
                //节点流
                FileOutputStream fileOutputStream = null;
                //功能流
                DataOutputStream dataOutputStream = null;
                try {
                    fileOutputStream = new FileOutputStream(path, false);
                    dataOutputStream = new DataOutputStream(fileOutputStream);
                    //dataOutputStream提供数据类型的写
                    //注意这里的顺序
                    dataOutputStream.writeInt(stu1.getId());
                    dataOutputStream.writeUTF(stu1.getName());
                    dataOutputStream.writeInt(stu1.getAge());
                    dataOutputStream.writeUTF(stu1.getLocalDate()
                            .format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                    dataOutputStream.flush();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        dataOutputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

DataInputStream操作

public class MyApp2 {
            public static void main(String[] args) {
                String path = "d:\\mystu1.hzj";
                FileInputStream fileInputStream = null;
                DataInputStream dataInputStream = null;
                try {
                    fileInputStream = new FileInputStream(path);
                    dataInputStream = new DataInputStream(fileInputStream);
                    //怎么进的,就怎么出
                    int id = dataInputStream.readInt();
                    String name = dataInputStream.readUTF();
                    int age = dataInputStream.readInt();
                    String localdate = dataInputStream.readUTF();
                    Stu stu2 = new Stu();
                    stu2.setId(id);
                    stu2.setName(name);
                    stu2.setAge(age);
                    stu2.setLocalDate(LocalDate.parse(localdate));
                    System.out.println(stu2);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        dataInputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

ClassRoom类实现序列化标记,并且编写序列化版本

//Serializable接口是一个标记,代表可以让系统序列化该类
        public class ClassRoom implements Serializable {
            //序列化是有版本的
            private static final long serialVersionUID = 100;
            //transient禁止序列化修饰符,
            //transient int id; 这样的化id属性就无法序列化了,也不会反序列
            int id;
            String name;

            public ClassRoom(int id, String name) {
                this.id = id;
                this.name = name;
            }

            public ClassRoom() {
            }

            @Override
            public String toString() {
                return "ClassRoom{" +
                        "id=" + id +
                        ", name='" + name + '\'' +
                        '}';
            }

            public int getId() {
                return id;
            }

            public void setId(int id) {
                this.id = id;
            }

            public String getName() {
                return name;
            }

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

ObjectOutputStream操作

public class MyApp3 {
            public static void main(String[] args) {
                ClassRoom classRoom1 = new ClassRoom();
                classRoom1.setId(1001);
                classRoom1.setName("2109");
                String path = "d:\\classroom.hzj";
                FileOutputStream fileOutputStream = null;
                ObjectOutputStream objectOutputStream = null;
                try {
                    fileOutputStream = new FileOutputStream(path, false);
                    objectOutputStream = new ObjectOutputStream(fileOutputStream);
                    //writeObject新功能
                    //序列化【把对象存起来】
                    //java.io.NotSerializableException
                    //被序列化的类必须要实现一个接口Serializable
                    //序列化是有版本号的,如果不写会默认有一个,但是这里是强调要写。
                    //private static final long serialVersionUID = 100;
                    objectOutputStream.writeObject(classRoom1);
                    objectOutputStream.flush();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        objectOutputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

ObjectInputStream操作

public class MyApp4 {
            public static void main(String[] args) {
                String path = "d:\\classroom.hzj";
                FileInputStream fileInputStream = null;
                ObjectInputStream objectInputStream = null;
                try {
                    fileInputStream = new FileInputStream(path);
                    objectInputStream = new ObjectInputStream(fileInputStream);
                    //反序列化
                    Object o = objectInputStream.readObject();
                    ClassRoom classRoom = (ClassRoom) o;
                    System.out.println(classRoom);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        objectInputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

六、反射

反射的概念

Java中?Class类代表类的结构

Class类的?个对象就是反射对象

Class类的?个对象就是某?个类的结构描述

Class类如何构造

静态?法forName

类.class

象.getClass()

反射的操作

  • 查看类信息(查看类的结构)
    • 只能访问修饰符允许访问的范围getxxx();

    • 可以访问任意修饰符范围的getDeclaredxxx();

类的结构?般分为以下?种

  • Field字段类

  • getDeclaredFields()获取所有字段

  • Method?法类

    • getDeclaredMethods()获取所有?法
  • Parameter?法形参类

    • getParameters()获取所有形参
  • Constructor构造?法类

    • getDeclaredConstructors()获取所有构造?法
  • Annotation注解类

    • getAnnotations()获取所有注解
public class MyApp {
            //Class对象是什么反射对象(Class对象是什么某个类定义的结构)
            public static void main(String[] args) {
                //反射创建对象
                //任何一个类都有一个反射类Class
                //创建一个反射类的对象,即创建一个Class类的对象
                //反射类对象的构造,使用静态方法
                try {
                    String classSrc = "com.bjpowernode.beans.Stu";
                    Class stuClass = Class.forName(classSrc);
                    //返回类中字段信息
                    //stuClass.getxxx();只能访问修饰符允许访问的范围
                    //stuClass.getDeclaredxxx();可以访问任意修饰符范围的
                    //Field[] fields = stuClass.getFields();
                    //查看所有字段
                    Field[] fields = stuClass.getDeclaredFields();
                    for (Field temp : fields) {
                        //设置访问权限
                        //temp.setAccessible(true);
                        System.out.println(temp.getName());
                    }
                    System.out.println("********************************************
                            //查看所有方法
                            Method[]declaredMethods = stuClass.getDeclaredMethods();
                    for (Method temp : declaredMethods) {
                        //temp.getReturnType()返回方法的返回类型的反射形
                        Class returnType = temp.getReturnType();
                        System.out.println("返回类型:" + returnType.getName());
                        System.out.println("方法名:" + temp.getName());
                        System.out.println("参数列表:");
                        //返回参数列表
                        Parameter[] parameters = temp.getParameters();
                        for (Parameter temp2 : parameters) {
                            //参数类型
                            System.out.println("参数返回类型:" + temp2.getType().getN
                                    //参数名称【JVM中是不需要知道参数名称的】
                                    System.out.println("参数名称:" + temp2.getName());
                        }
                        System.out.println("*****************************");
                    }
                    System.out.println("*************构造方法****************");
                    //查看所有构造方法
                    Constructor[] declaredConstructors = stuClass.getDeclaredConstru
                    for (Constructor temp : declaredConstructors) {
                        //temp.getReturnType()返回方法的返回类型的反射形
                        System.out.println("方法名:" + temp.getName());
                        System.out.println("参数列表:");
                        //返回参数列表
                        Parameter[] parameters = temp.getParameters();
                        for (Parameter temp2 : parameters) {
                            //参数类型
                            System.out.println("参数返回类型:" + temp2.getType().getN
                                    //参数名称【JVM中是不需要知道参数名称的】
                                    System.out.println("参数名称:" + temp2.getName());
                        }
                        System.out.println("*****************************");
                    }
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }

构造类

执?类属性

执?类?法

七、注解

注解的作用

  • 注解是使?特定的符号和属性来完成特定的功能

    • 符号是@xxxxxx
    • 属性是@xxxx(xxx=xxx,xxx=xxx)
    • 注解使??常简单,完成的特定功能都是封装了Java代码
  • 注解的?命周期

    • 活在源代码(给?看,相当于注释)

      RetentionPolicy.SOURCE

    • 活在字节码(class字节码可以解析,相当于给字节码程序员当注释,字节码程序员可以利 ?该注解完成某些功能)

      RetentionPolicy.CLASS

    • 活在运?时(JVM)(JVM需要执?的,对功能有影响)

      RetentionPolicy.RUNTIME

  • 注解可以?在哪?(Java源码)

    注解可以写的地?由ElementType枚举类定义的地?

注解的使?

看注解的定义

看注解的功能

自定义操作

注解的声明(?定义注解)

注解是?个接?,但是需要在接?前?使?@符号

//Override是注解名称
//@interface是注解,所以区别于interface接口,但是注解就是接口
public @interface Override

注解?命周期定义(?在注解上?的注解叫元注解)

使用@Retention
具体的什么周期使用RetentionPolicy枚举

注解能?在什么地?

使用@Target
具体的位置使用ElementType枚举

注解能?的地?可以是多个(也就是说@Target可以声明出多个地?)

注解结构

属性(不带默认值的属性、带默认值的属性)

		//生命周期
        @Retention(RetentionPolicy.SOURCE)
        //能写在哪里(一般都会只定义写在一个地方,很少定义同时写到多个地方)
        @Target({ElementType.TYPE, ElementType.FIELD})
        public @interface MyAnnotaion {
            //注解属性
            //不带默认值 数据类型 属性名()
            //带默认值的 数据类型 属性名() default 值
            String name() default "hzj";

            //如果该属性没有默认值,则使用注解的时候必须填
            int age();

            int[] arrayAH();
            //属性的数据类型,只能基本属性类型、字符串型、Class类型,其它的自定义类型等不可以
            //容器可以是数组(但是只能是一维),但是不能是集合
            //ArrayList cl();
        }

八、线程

1.进程(由线程组成)

  • 进程就是程序的?命周期,应?程序开始,进程开始,应?程序结束,进程结束

  • 程序运?在操作系统上,进程是程序的单位

  • 进程由线程组成,?个进程的启动,?少要有?个线程

  • Java程序中,主启动?法(???法)为main?法启动后?即产?了?个main线程(主线程)

  • 进程拥有?命周期

    • ?个程序开始,进程开始
    • 进程内的所有线程结束,则进程结束

2.线程

线程是进程的组成单位

线程拥有?命周期

线程由?法体语句组成

  • native?法(抽象?法,调?C语?的?法,Java可以和C语?通信)

在?个类class??会可以存在抽象?法,但是必须是native?法

native?法是指调?本地?法(该本地?法指的是C或C++语法的?法)

native?法意味着该?法并不是Java语法实现的,因此需要采?JNI技术来调?C或C++?法

?般来说涉及到了操作系统的底层或者直接要与硬件通信,通常会使?C语?处理,?Java采?navtic修饰符修饰?身的抽象?法,代表调?C语?的?法。

Thread类

thread代表线程

获取当前线程

静态?法:currentThread() 获取线程名称

对象?法:getName()

线程的创建

语法层?(都会使?实现runnable接?的?法来创建线程)

  • 继承Thread类(如果直接继承Thread类,那么就?法继承其他类)

    • 继承Thread类
    • 重写run?法
    • 使?Thread对象的start?法启动线程
    • 实现Runnable接?(都会采?该?法)(因为没有?继承,因此还可以继承其它的类)
  • 实现Runnable接?

    • 重写run?法
    • 使??个Thread对象与Runnable进?关联
MyThreadB myThreadB=new MyThreadB();
//与Thread建立关联
Thread thread=new Thread(myThreadB);
thread.setName("MyThreadB线程");
thread.start();

使?Thread对象的start?法启动线程

内存层?

  • 创建?个线程就是创建了?个栈

  • 异步:就在不同栈中执??法,就是异步执?

  • 堆是数据存储的,堆??的对象是线程共享的

  • 栈是线程私有

线程处理共享数据的问题

  • 多个线程处理共享数据(?如对象,?如静态资源),会造成线程安全问题。

  • 我们会采?同步策略解决问题

    • 加同步锁

常??法

  • currentThread()
    • 获取当前线程
  • sleep()
    • 线程阻塞,若?毫秒后?动唤醒
    • 可以被中断(可以提前唤醒)
    • 使?TimeUnit替代Thread.sleep,可以优雅的,仅此?已
public class MyApp6 {
public static void main(String[] args) {
//线程想休眠3小时24分17秒88毫秒
//一般方案
try {
Thread.sleep(12257088L);
} catch (InterruptedException e) {
e.printStackTrace();
}
//线程想休眠3小时24分17秒88毫秒
//优雅方案
try {
TimeUnit.HOURS.sleep(3);
TimeUnit.MINUTES.sleep(24);
TimeUnit.SECONDS.sleep(17);
TimeUnit.MILLISECONDS.sleep(88);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
  • setName/getName

    设置线程名称,底层是?个char数组(猜想:因为c没有字符串,c的字符串是char数 组)

  • sAlive()

    查询线程是否启动并没终?状态

  • getId()

    线程唯?ID,底层是?个简单的?增的整数

  • yield()

    ?法的作?是放弃当前的CPU资源(不确定)

  • setPriority()

    设置线程优先级(不确定)

  • setDaemon()

    设置后台线程

    后台线程不可单独运?(如果全是后台线程,则?即??消亡)

package com.bjpowernode.thread;
//测试后台线程,进程中只有后台线程,那么后台线程立即死亡
public class MyT4 implements Runnable{
@Override
public void run() {
while (true){
System.out.println("okokokko");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.bjpowernode.app;
import com.bjpowernode.thread.MyT4;
public class MyApp4 {
public static void main(String[] args) {
MyT4 myT4=new MyT4();
Thread thread=new Thread(myT4,"myT4");
//这里设置一个后台线程,并且该线程是死循环
thread.setDaemon(true);
//开启线程,然后什么都不会打印,线程就死掉了
thread.start();
}
}

3.中断

  • 中断可以中断的?法有

    sleep

    join

  • 中断有三个?法

线程对象中断操作

  • interrupt()【如果没有遇到需要唤醒的线程,则保留标记位为true,唤醒后则标记位为 false】

  • 该?法可以让Thread.sleep唤醒(也就是中断Thread的sleep让其提前唤醒

    • 被中断的sleep会出现在catch块中(也就是Java使?了try catch捕获中断

线程类静态判断中断(使?后会修改标记位,并修改为false)

  • interrupted()【该?法属于静态?法Thread.interrupted()】

    • 判断中断?法是否使?过,采?的标记位?法

      如果interrupt()?法没有中断(也就是没有踢掉sleep)则interrupted返回true

      如果interrupt()?法有中断(也就是有踢掉sleep)则interrupted返回false

    • 若没有interrupt()?法,则interrupted的标记位false

  • interrupted()?法执?过后会修改标记位为false

线程对象判断中断(该?法属于对象?法Thread.currentThread().isInterrupted())

  • 判断中断?法是否使?过,采?的标记位?法

    如果interrupt()?法没有中断(也就是没有踢掉sleep)则interrupted返回true

    如果interrupt()?法有中断(也就是有踢掉sleep)则interrupted返回false

  • 若没有interrupt()?法,则interrupted的标记位false

    isInterrupted()?法执?过后不会修改标记位

interrupt()中断sleep

package com.bjpowernode.thread;
//interrupt()中断sleep
public class MyT2 implements Runnable{
@Override
public void run() {
//执行中断开始设计标记位为true,
//碰到sleep将会立即中断sleep线程将其唤醒
Thread.currentThread().interrupt();
try {
//开始sleep
//interrupt()可以将其唤醒
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("被踢了");
}
//判断中断标记位【这里使用的是Thread.interrupted()】
//判断后会修改标记位为false
System.out.println(Thread.interrupted());
}
}
package com.bjpowernode.app;
import com.bjpowernode.thread.MyT2;
//interrupt()中断sleep
public class MyApp2 {
public static void main(String[] args) {
MyT2 myT2=new MyT2();
Thread thread=new Thread(myT2,"myT2");
thread.start();
}
}

main线程中中断thread线程

package com.bjpowernode.thread;
//在外界使用interrupt()方法中断本线程
public class MyT1 implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(i);
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("MyT1的被踢醒");
}
}
}
}
package com.bjpowernode.app;
import com.bjpowernode.thread.MyT1;
public class MyApp {
public static void main(String[] args) {
MyT1 myT1=new MyT1();
Thread thread=new Thread(myT1,"线程1");
thread.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//使用main线程中断thread线程【也就是不在thread自己里面中断自己】
thread.interrupt();
}
}

Thread.currentThread().isInterrupted()调?后不会修改标记位

package com.bjpowernode.thread;
//测试Thread.currentThread().isInterrupted()判断标记位后,不会改变标记位
public class MyT5 implements Runnable{
@Override
public void run() {
//调用中断
Thread.currentThread().interrupt();
//打印中断标记位,这里为true,并且不会改变标记位
System.out.println(Thread.currentThread().isInterrupted());
//打印中断标记位,这里为true,并且不会改变标记位
System.out.println(Thread.currentThread().isInterrupted());
}
}
package com.bjpowernode.app;
import com.bjpowernode.thread.MyT5;
//测试Thread.currentThread().isInterrupted()判断标记位后,不会改变标记位
public class MyApp5 {
public static void main(String[] args) {
MyT5 myT5 =new MyT5();
Thread thread1=new Thread(myT5,"xxx");
thread1.start();
}
}

Thread.interrupted()调?后会修改标记位为false

package com.bjpowernode.thread;
//测试Thread.interrupted()判断标记位后,会改变标记位为false
public class MyT3 implements Runnable {
@Override
public void run() {
//调用中断
Thread.currentThread().interrupt();
//打印中断标记位,这里为true,并且会改变标记位为false
System.out.println(Thread.interrupted());
//打印中断标记位,这里为false,因为被上面的Thread.interrupted()修改了
System.out.println(Thread.interrupted());
}
}
package com.bjpowernode.app;
import com.bjpowernode.thread.MyT3;
//测试Thread.interrupted()判断标记位后,会改变标记位为false
public class MyApp3 {
public static void main(String[] args) {
MyT3 myT3 =new MyT3();
Thread thread1=new Thread(myT3,"xxx");
thread1.start();
}
}

join

  • 线程A在线程B中执?了A.join(),则B进?等待,直到线程A结束?命周期,或者到达给定的 时间,那么B线程继续执?

  • join?法会使当前线程永远地等待下去,直到期间被另外的线程中断,或者join的线程执? 结束

状态

  • 线程的状态由Thread.State枚举常量标识:

  • NEW——线程还没有开始执?。

  • RUNNABLE——线程正在JVM中执?

  • BLOCKED——线程被阻塞并等待?个监听锁

  • WAITING——线程?限期地等待另外?条线程执?特定的操作

  • TIMED_WAITING——线程在特定的时间内等待另外?条线程执?某种操作。

  • TERMINATED——线程?经退出

  • 判断线程状态的?些?法

    • isAlive()检查线程是否已经启动且还没有结束状态
    • getState()?法直接获取线程对象的状态
package com.bjpowernode.thread;
//线程状态查看
public class MyT7 implements Runnable {
@Override
public void run() {
//RUNNABLE状态
//thread线程开始执行状态
System.out.println("RUNNABLE-1状态测试:"+Thread.currentThread().getSt
System.out.println("ok");
try {
//thread线程开始休眠
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
//RUNNABLE状态
//thread线程休眠被中断,开始执行
System.out.println("RUNNABLE-3状态测试(唤醒):"+Thread.currentThr
}
//RUNNABLE状态
//thread线程继续执行
System.out.println("RUNNABLE-2状态测试:"+Thread.currentThread().getSt
}
}
package com.bjpowernode.app;
import com.bjpowernode.thread.MyT7;
//获取线程的当前状态
//尝试自己写出打印语句,并且正好是thread对象所处的某种状态
public class MyApp7 {
public static void main(String[] args) {
MyT7 myT7=new MyT7();
Thread thread=new Thread(myT7,"myT7");
//NEW状态
//thread线程刚刚新建
System.out.println("NEW状态测试:"+thread.getState());
//thread线程刚刚开始
thread.start();
//这里main线程休眠500,目的是为了让thread线程抢到CPU进入休眠
//为下面打印thread线程休眠状态提供支持
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//TIMED_WAITING状态
//thread线程开始休眠
System.out.println("TIMED_WAITING状态测试:"+thread.getState());
//唤醒thread
//thread线程休眠被唤醒
thread.interrupt();
//这里main线程休眠3000,目的是为了让thread线程抢到CPU,并执行完毕
//为下面打印thread线程结束状态提供支持
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//TERMINATED状态
//thread已经执行结束(这里利用时间差预判thread已经执行结束)
System.out.println("TERMINATED状态测试:"+thread.getState());
}
}

?命周期

  • 线程从?到死的状态变化

  • 执?各种线程?法后,线程的状态变化

线程关闭【thread.stop();已经被废除】

  • 正常关闭,线程执?完毕即关闭

  • 捕获中断信号关闭线程【这?不推荐使?该?法来设计线程关闭】

println(Thread.interrupted());
//打印中断标记位,这里为false,因为被上面的Thread.interrupted()修改了
System.out.println(Thread.interrupted());
}
}
package com.bjpowernode.app;
import com.bjpowernode.thread.MyT3;
//测试Thread.interrupted()判断标记位后,会改变标记位为false
public class MyApp3 {
public static void main(String[] args) {
MyT3 myT3 =new MyT3();
Thread thread1=new Thread(myT3,“xxx”);
thread1.start();
}
}


 join

- 线程A在线程B中执?了A.join(),则B进?等待,直到线程A结束?命周期,或者到达给定的 时间,那么B线程继续执?

- join?法会使当前线程永远地等待下去,直到期间被另外的线程中断,或者join的线程执? 结束  

 状态 

-  线程的状态由Thread.State枚举常量标识: 
  -  NEW——线程还没有开始执?。  
  -  RUNNABLE——线程正在JVM中执?  
  -  BLOCKED——线程被阻塞并等待?个监听锁  
  -  WAITING——线程?限期地等待另外?条线程执?特定的操作 
  -   TIMED_WAITING——线程在特定的时间内等待另外?条线程执?某种操作。 
  -  TERMINATED——线程?经退出 

- 判断线程状态的?些?法
  - isAlive()检查线程是否已经启动且还没有结束状态
  -  getState()?法直接获取线程对象的状态 

package com.bjpowernode.thread;
//线程状态查看
public class MyT7 implements Runnable {
@Override
public void run() {
//RUNNABLE状态
//thread线程开始执行状态
System.out.println(“RUNNABLE-1状态测试:”+Thread.currentThread().getSt
System.out.println(“ok”);
try {
//thread线程开始休眠
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
//RUNNABLE状态
//thread线程休眠被中断,开始执行
System.out.println(“RUNNABLE-3状态测试(唤醒):”+Thread.currentThr
}
//RUNNABLE状态
//thread线程继续执行
System.out.println(“RUNNABLE-2状态测试:”+Thread.currentThread().getSt
}
}
package com.bjpowernode.app;
import com.bjpowernode.thread.MyT7;
//获取线程的当前状态
//尝试自己写出打印语句,并且正好是thread对象所处的某种状态
public class MyApp7 {
public static void main(String[] args) {
MyT7 myT7=new MyT7();
Thread thread=new Thread(myT7,“myT7”);
//NEW状态
//thread线程刚刚新建
System.out.println(“NEW状态测试:”+thread.getState());
//thread线程刚刚开始
thread.start();
//这里main线程休眠500,目的是为了让thread线程抢到CPU进入休眠
//为下面打印thread线程休眠状态提供支持
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//TIMED_WAITING状态
//thread线程开始休眠
System.out.println(“TIMED_WAITING状态测试:”+thread.getState());
//唤醒thread
//thread线程休眠被唤醒
thread.interrupt();
//这里main线程休眠3000,目的是为了让thread线程抢到CPU,并执行完毕
//为下面打印thread线程结束状态提供支持
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//TERMINATED状态
//thread已经执行结束(这里利用时间差预判thread已经执行结束)
System.out.println(“TERMINATED状态测试:”+thread.getState());
}
}


?命周期

- 线程从?到死的状态变化

- 执?各种线程?法后,线程的状态变化  

 线程关闭【thread.stop();已经被废除】

- 正常关闭,线程执?完毕即关闭

- 捕获中断信号关闭线程【这?不推荐使?该?法来设计线程关闭】

- 使?标记控制【最好使? volatile修饰 】
文章来源:https://blog.csdn.net/Peng_423/article/details/135708575
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。