导图社区 JAVA学习思维导图
这是一篇关于JAVA学习的思维导图。该思维导图深入地归纳总结了关于这一部分内容的知识点,可帮助系统复习备考。
编辑于2021-08-19 21:33:43JAVA(基础)
基本概念
环境搭建
JDK: Java开发工具包,JDK=JRE+开发工具(javac.exe,java.exe,javadoc.exe)
JRE: Java运行环境,JRE=JVM+核心类库(String,Math,Date,Collection,IO等等)
JVM: Java虚拟机(详见另一图)
注释
单行注释://
多行注释:/**/
文档注释:/** */
@author
@version
@param
@return
包
同一包内不能定义同名的类
标识符
为方法、变量或其他用户定义项所定义的名称,Java 区分大小写
标识符由数字(0~9)和字母(A~Z 和 a~z)、美元符号($)、下划线(_)以及 Unicode 字符集中符号大于 0xC0 的所有符号组合构成(各符号之间没有空格)
标识符的第一个符号为字母、下划线和美元符号,后面可以是任何字母、数字、美元符号或下划线。
关键字
关键字(或者保留字)是对编译器有特殊意义的固定单词,不能在程序中做其他目的使用。关键字具有专门的意义和用途,和自定义的标识符不同,不能当作一般的标识符来使用。
1、数据类型:boolean、int、long、short、byte、float、double、char、class、interface。
2、流程控制:if、else、do、while、for、switch、case、default、break、continue、return、try、catch、finally。
3、修饰符:public、protected、private、final、void、static、strict、abstract、transient、synchronized、volatile、3native
4、动作:package、import、throw、throws、extends、implements、this、supper、instanceof、new
5、保留字:true、false、null、goto、const。
常量
常量值又称为字面常量,它是通过数据直接表示的
变量
基本数据类型
数值型
整型(byte,short,int,long)
浮点类型(float,double)
字符型(char)
布尔型(boolean)
引用数据类型
类(class)
接口(interface)
数组(array[])
变量的分类
局部变量:在方法中声明的变量,必须要赋初值
实例变量:声明在类中,可以没有初值,也称成员变量,独立于方法之外
类变量:也称静态变量,用static修饰,必须声明在方法之外
修饰符

访问控制修饰符
public、protected(不能修饰类)、default、private(不能修饰类)
static
静态变量
final
final变量:不能被重新赋值
final方法:不能被子类重写
final类:不能被继承
abstract
抽象类
不能实例化对象
可以包含抽象和非抽象方法
如果包含了抽象方法,则必须声明为抽象类
抽象方法
不能为final和static
没有方法体,如果子类不是抽象类,则必须实现父类的抽象方法
synchronized
详见多线程部分
transient
序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。
volatile
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。 一个 volatile 对象引用可能是 null。 实例 public class MyRunnable implements Runnable { private volatile boolean active; public void run() { active = true; while (active) // 第一行 { // 代码 } } public void stop() { active = false; // 第二行 } } 通常情况下,在一个线程调用 run() 方法(在 Runnable 开启的线程),在另一个线程调用 stop() 方法。 如果 第一行 中缓冲区的 active 值被使用,那么在 第二行 的 active 值为 false 时循环不会停止。 但是以上代码中我们使用了 volatile 修饰 active,所以该循环会停止。
运算符
算术运算符
+ - * / % ++ --
关系运算符
== != > < >= <=
位运算符
& | ^ ~ << >> >>>按位右移补零
逻辑运算符
&& || !
赋值运算符
= += -= /= *= (%)= <<= >>= &= ^= |=
其他运算符
?: instanceof
运算符优先级

后缀>一元(++)>乘性>加性>移位>关系>相等>按位与>按位异或>按位或>逻辑与>逻辑或>条件运算符>赋值>逗号
循环结构
for
while
do...while
break
跳出当前循环
continue
跳过本次循环,执行下一次循环
增强for(java5之后)
for(声明语句:表达式){ //代码 }
条件语句
if...else
switch..case
switch(expression){ case value : //语句 break; //可选 case value : //语句 break; //可选 //你可以有任意数量的case语句 default : //可选 //语句 }
switch 语句中的变量类型可以是: byte、short、int 或者 char。从 Java SE 7 开始,switch 支持字符串 String 类型了,同时 case 标签必须为字符串常量或字面量。
String
charsequence
AbstractStringBuilder
StringBuilder
StringBuffer
Appendable
String str = "字符串";
字符串创建在公共池中
String str2= new String("字符串");
字符串创建在堆上
String常用方法
1、char charAt(int index) :返回指定索引处的 char 值。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 2、int compareTo(Object o):把这个字符串和另一个对象比较。 3、int compareTo(String anotherString):按字典顺序比较两个字符串。 4、int compareToIgnoreCase(String str):按字典顺序比较两个字符串,不考虑大小写。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 5、String concat(String str):将指定字符串连接到此字符串的结尾。也可以用+连接两个字符串 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 6、boolean contentEquals(StringBuffer sb):当且仅当字符串与指定的StringBuffer有相同顺序的字符时候返回真。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 7、static String copyValueOf(char[] data):返回指定数组中表示该字符序列的 String。 8、static String copyValueOf(char[] data, int offset, int count):返回指定数组中表示该字符序列的 String ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 9、boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 10、boolean equals(Object anObject):将此字符串与指定的对象比较。 11、boolean equalsIgnoreCase(String anotherString):将此 String 与另一个 String 比较,不考虑大小写。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 12、byte[] getBytes(): 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 13、byte[] getBytes(String charsetName):使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 14、void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin):将字符从此字符串复制到目标字符数组。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 15、int indexOf(int ch):返回指定字符在此字符串中第一次出现处的索引。 16、int indexOf(int ch, int fromIndex):返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。 17、int indexOf(String str): 返回指定子字符串在此字符串中第一次出现处的索引 18、int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 19、int lastIndexOf(int ch): 返回指定字符在此字符串中最后一次出现处的索引 20、int lastIndexOf(int ch, int fromIndex):返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索。 21、int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引。 22、int lastIndexOf(String str, int fromIndex): 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 23、int length():返回此字符串的长度。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 24、String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。 25、String replaceAll(String regex, String replacement):使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 26、String replaceFirst(String regex, String replacement): 使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 27、String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。 28、String[] split(String regex, int limit):根据匹配给定的正则表达式来拆分此字符串。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 29、boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始。 30、boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 31、CharSequence subSequence(int beginIndex, int endIndex): 返回一个新的字符序列,它是此序列的一个子序列。 32、String substring(int beginIndex):返回一个新的字符串,它是此字符串的一个子字符串。 33、String substring(int beginIndex, int endIndex):返回一个新字符串,它是此字符串的一个子字符串。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 34、char[] toCharArray():将此字符串转换为一个新的字符数组。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 35、String toLowerCase():使用默认语言环境的规则将此 String 中的所有字符都转换为小写。 36、String toLowerCase(Locale locale): 使用给定 Locale 的规则将此 String 中的所有字符都转换为小写。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 37、String toString(): 返回此对象本身(它已经是一个字符串!)。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 38、String toUpperCase():使用默认语言环境的规则将此 String 中的所有字符都转换为大写。 39、String toUpperCase(Locale locale):使用给定 Locale 的规则将此 String 中的所有字符都转换为大写。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 40、String trim():返回字符串的副本,忽略前导空白和尾部空白。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 41、static String valueOf(primitive data type x):返回给定data type类型x参数的字符串表示形式。(其他类型转字符串) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 42、contains(CharSequence chars):判断是否包含指定的字符系列。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 43、isEmpty():判断字符串是否为空。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 44、boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。 45、boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len):测试两个字符串区域是否相等。 46、boolean regionMatches(int toffset, String other, int ooffset, int len):测试两个字符串区域是否相等。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 47、String intern(): 返回字符串对象的规范化表示形式。如果常量池中已经有了此字符串,那么将常量池中该字符串的引用返回,如果没有,那么将该字符串对象添加到常量池中,并且将引用返回。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 48、int hashCode():返回此字符串的哈希码。
String转int
Integer.parseInt(str)
Integer.valueOf(str).intValue()
int转String
String.valueOf(i);
Integer.toString(i);
"" + i;
parselxxx
将字符串转换为xxx
a.valueOf
参数转换为a类型
toString
将其他类型转换为字符串
StringBuffer
可修改的字符序列,,JAVA5,线程安全,速度慢
StringBuffer常用方法
1、public insert(int offset, int i):将 int 参数的字符串表示形式插入此序列中。 2、insert(int offset, String str):将 str 参数的字符串插入此序列中。 ----------------------------------------------------------------------------------------------------------------------------------------------- 3、public delete(int start, int end):移除此序列的子字符串中的字符。 ----------------------------------------------------------------------------------------------------------------------------------------------- 4、public StringBuffer append(String s):将指定的字符串追加到此字符序列。 ----------------------------------------------------------------------------------------------------------------------------------------------- 5、public StringBuffer reverse(): 将此字符序列用其反转形式取代。 ----------------------------------------------------------------------------------------------------------------------------------------------- 6、replace(int start, int end, String str):使用给定 String 中的字符替换此序列的子字符串中的字符。 ----------------------------------------------------------------------------------------------------------------------------------------------- 7、int capacity():返回当前容量。 ----------------------------------------------------------------------------------------------------------------------------------------------- 8、char charAt(int index):返回此序列中指定索引处的 char 值。 ----------------------------------------------------------------------------------------------------------------------------------------------- 9、void ensureCapacity(int minimumCapacity):确保容量至少等于指定的最小值。 ----------------------------------------------------------------------------------------------------------------------------------------------- 10、void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin):将字符从此序列复制到目标字符数组 dst。 ----------------------------------------------------------------------------------------------------------------------------------------------- 11、int indexOf(String str):返回第一次出现的指定子字符串在该字符串中的索引。 12、int indexOf(String str, int fromIndex):从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引。 ----------------------------------------------------------------------------------------------------------------------------------------------- 13、int lastIndexOf(String str):返回最右边出现的指定子字符串在此字符串中的索引。 14、int lastIndexOf(String str, int fromIndex):返回 String 对象中子字符串最后出现的位置。 ----------------------------------------------------------------------------------------------------------------------------------------------- 15、int length(): 返回长度(字符数)。 ----------------------------------------------------------------------------------------------------------------------------------------------- 16、void setCharAt(int index, char ch):将给定索引处的字符设置为 ch。 ----------------------------------------------------------------------------------------------------------------------------------------------- 17、void setLength(int newLength):设置字符序列的长度。 ----------------------------------------------------------------------------------------------------------------------------------------------- 18、CharSequence subSequence(int start, int end):返回一个新的字符序列,该字符序列是此序列的子序列。 ----------------------------------------------------------------------------------------------------------------------------------------------- 19、String substring(int start):返回一个新的 String,它包含此字符序列当前所包含的字符子序列。 20、String substring(int start, int end):返回一个新的 String,它包含此序列当前所包含的字符子序列。 ----------------------------------------------------------------------------------------------------------------------------------------------- 21、String toString():返回此序列中数据的字符串表示形式。
初始容量为16
StringBuilder
可修改的字符序列,JAVA5,线程不安全,速度快
数组
数组是用来存储固定大小的同类型元素。
声明并创建
dataType[] arrayRefVar = new dataType[arraySize];; // 首选的方法
dataType arrayRefVar[] = new dataType[arraySize];; // 效果相同,但不是首选方法
多维数组
dataType[][] arrayRefVar = new dataTtpe[line][column];
Arrays类
Arrays常用方法
1)int binarySearch(type[] a, type key) 使用二分法查询 key 元素值在 a 数组中出现的索引,如果 a 数组不包含 key 元素值,则返回负数。调用该方法时要求数组中元素己经按升序排列,这样才能得到正确结果。 2)int binarySearch(type[] a, int fromIndex, int toIndex, type key) 这个方法与前一个方法类似,但它只搜索 a 数组中 fromIndex 到 toIndex 索引的元素。调用该方法时要求数组中元素己经按升序排列,这样才能得到正确结果。 3)type[] copyOf(type[] original, int length) 这个方法将会把 original 数组复制成一个新数组,其中 length 是新数组的长度。如果 length 小于 original 数组的长度,则新数组就是原数组的前面 length 个元素,如果 length 大于 original 数组的长度,则新数组的前面元索就是原数组的所有元素,后面补充 0(数值类型)、false(布尔类型)或者 null(引用类型)。 4)type[] copyOfRange(type[] original, int from, int to) 这个方法与前面方法相似,但这个方法只复制 original 数组的 from 索引到 to 索引的元素。 5)boolean equals(type[] a, type[] a2) 如果 a 数组和 a2 数组的长度相等,而且 a 数组和 a2 数组的数组元素也一一相同,该方法将返回 true。 6)void fill(type[] a, type val) 该方法将会把 a 数组的所有元素都赋值为 val。 7)void fill(type[] a, int fromIndex, int toIndex, type val) 该方法与前一个方法的作用相同,区别只是该方法仅仅将 a 数组的 fromIndex 到 toIndex 索引的数组元素赋值为 val。 8)void sort(type[] a) 该方法对 a 数组的数组元素进行排序。 9)void sort(type[] a, int fromIndex, int toIndex) 该方法与前一个方法相似,区别是该方法仅仅对 fromIndex 到 toIndex 索引的元素进行排序。 10)String toString(type[] a) 该方法将一个数组转换成一个字符串。该方法按顺序把多个数组元素连缀在一起,多个数组元素使用英文逗号,和空格隔开。 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++JAVA8+++++++++++++++++++++++++++++++++++++++++++++++++++++ 1)oid parallelPrefix(xxx[] array, XxxBinaryOperator op) 该方法使用 op 参数指定的计算公式计算得到的结果作为新的元素。op 计算公式包括 left、right 两个形参,其中 left 代表数组中前一个索引处的元素,right 代表数组中当前索引处的元素,当计算第一个新数组元素时,left 的值默认为 1。 2)void parallelPrefix(xxx[] array, int fromIndex, int toIndex, XxxBinaryOperator op) 该方法与上一个方法相似,区别是该方法仅重新计算 fromIndex 到 toIndex 索引的元素。 3)void setAll(xxx[] array, IntToXxxFunction generator) 该方法使用指定的生成器(generator)为所有数组元素设置值,该生成器控制数组元素的值的生成算法。 4)void parallelSetAll(xxx[] array, IntToXxxFunction generator) 该方法的功能与上一个方法相同,只是该方法增加了并行能力,可以利用多 CPU 并行来提高性能。 5)void parallelSort(xxx[] a) 该方法的功能与 Arrays 类以前就有的 sort() 方法相似,只是该方法增加了并行能力,可以利用多 CPU 并行来提高性能。 6)void parallelSort(xxx[] a,int fromIndex, int toIndex) 该方法与上一个方法相似,区別是该方法仅对 fromIndex 到 toIndex 索引的元素进行排序。 7)Spliterator.OfXxx spliterator(xxx[] array) 将该数组的所有元素转换成对应的 Spliterator 对象。 8)Spliterator.OfXxx spliterator(xxx[] array, int startInclusive, int endExclusive) 该方法与上一个方法相似,区别是该方法仅转换 startInclusive 到 endExclusive 索引的元素。 9)XxxStream stream(xxx[] array) 该方法将数组转换为 Stream,Stream 是 Java 8 新增的流式编程的 API。 10)XxxStream stream(xxx[] array, int startInclusive, int endExclusive) 该方法与上一个方法相似,区别是该方法仅将 fromIndex 到 toIndex 索引的元索转换为 Stream。 上面方法列表中,所有以 parallel 开头的方法都表示该方法可利用 CPU 并行的能力来提高性能。上面方法中的 xxx 代表不同的数据类型,比如处理 int[] 型数组时应将 xxx 换成 int,处理 long[] 型数组时应将 XXX 换成 long。
互相转换
字符串转数组
toCharArray()
split()
数组转字符串
String.copyValueOf(charArray)
日期时间
Date类
Date(long millisec)
Date常用方法
1、boolean after(Date date):若当调用此方法的Date对象在指定日期之后返回true,否则返回false。 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 2、boolean before(Date date):若当调用此方法的Date对象在指定日期之前返回true,否则返回false。 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3、Object clone( ):返回此对象的副本。 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 4、int compareTo(Date date):比较当调用此方法的Date对象和指定日期。两者相等时候返回0。调用对象在指定日期之前则返回负数。调用对象在指定日期之后则返回正数 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 5、int compareTo(Object obj):若obj是Date类型则操作等同于compareTo(Date) 。否则它抛出ClassCastException。 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 6、boolean equals(Object date):当调用此方法的Date对象和指定日期相等时候返回true,否则返回false。 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 7、long getTime( ):返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 8、void setTime(long time):用自1970年1月1日00:00:00 GMT以后time毫秒数设置时间和日期。 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 9、String toString( ):把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 10、int hashCode( ): 返回此对象的哈希码值 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
getTime()
获取毫秒值
SimpleDateFormat()
选择任何用户自定义日期时间格式来运行
format
格式化
解析
日期时间格式化编码
使用printf格式化日期
Calender类
处理小时,日,分钟
Calendar c = Calendar.getInstance();
常用方法
1、void add(int field, int amount) 根据日历规则,将指定的(有符号的)时间量添加到给定的日历字段中。 2、 protected void computeFields() 转换UTC毫秒值为时间域值 3、 protected void computeTime() 覆盖Calendar ,转换时间域值为UTC毫秒值 4、 boolean equals(Object obj) 比较此 GregorianCalendar 与指定的 Object。 5、 int get(int field) 获取指定字段的时间值 6、 int getActualMaximum(int field) 返回当前日期,给定字段的最大值 7、 int getActualMinimum(int field) 返回当前日期,给定字段的最小值 8、 int getGreatestMinimum(int field) 返回此 GregorianCalendar 实例给定日历字段的最高的最小值。 9 、Date getGregorianChange() 获得格里高利历的更改日期。 10、 int getLeastMaximum(int field) 返回此 GregorianCalendar 实例给定日历字段的最低的最大值 11、 int getMaximum(int field) 返回此 GregorianCalendar 实例的给定日历字段的最大值。 12、 Date getTime() 获取日历当前时间。 13、 long getTimeInMillis() 获取用长整型表示的日历的当前时间 14、 TimeZone getTimeZone() 获取时区。 15、 int getMinimum(int field) 返回给定字段的最小值。 16、 int hashCode() 重写hashCode. 17、 boolean isLeapYear(int year) 确定给定的年份是否为闰年。 18、 void roll(int field, boolean up) 在给定的时间字段上添加或减去(上/下)单个时间单元,不更改更大的字段。 19、 void set(int field, int value) 用给定的值设置时间字段。 20、 void set(int year, int month, int date) 设置年、月、日的值。 21、 void set(int year, int month, int date, int hour, int minute) 设置年、月、日、小时、分钟的值。 22、 void set(int year, int month, int date, int hour, int minute, int second) 设置年、月、日、小时、分钟、秒的值。 23、 void setGregorianChange(Date date) 设置 GregorianCalendar 的更改日期。 24、 void setTime(Date date) 用给定的日期设置Calendar的当前时间。 25、 void setTimeInMillis(long millis) 用给定的long型毫秒数设置Calendar的当前时间。 26、 void setTimeZone(TimeZone value) 用给定时区值设置当前时区。 27、 String toString() 返回代表日历的字符串。
Add()
日期+, Add(Calendar.Date,count)
set()
设置Calendar示例的日期
get()
getTime()
setTime()
包装类
装箱
Integer integer = new Integer(10);
拆箱
integer.intValue()
方法
Java方法是语句的集合,它们在一起执行一个功能
修饰符 返回值类型 方法名(参数类型 参数名){ ... 方法体 ... return 返回值; }
方法的重载
可变形参
finalize() 方法
protected void finalize() { // 在这里终结代码 }
析构前调用
I/O流
包
java.io
字符流
Reader
BufferReader
(缓冲流)BufferedReader 类主要用于辅助其他字符输入流,它带有缓冲区,可以先将一批数据读到内存缓冲区。接下来的读操作就可以直接从缓冲区中获取数据,而不需要每次都从数据源读取数据并进行字符编码转换,这样就可以提高数据的读取效率。
InputStreamReader
FileReader
在给定要读取数据的文件的情况下创建一个新的 FileReader 对象。其中,file 表示要从中读取数据的文件。
将字节输入流转换为字符输入流,可以指定字符编码。
StringReader
将字符串转换为字符输入流,从中读取字符。
PipedReader
连接到一个 PipedWriter。
CharArrayReader
将字符数组转换为字符输入流,从中读取字符。
FilterReader
PushbackReader
Writer
BufferedWriter
为其他字符输出流提供写缓冲区。
OutputStreamWriter
FileWriter
将字节输出流转换为字符输出流,可以指定字符编码。
PrinterWriter
StringWriter
向内存缓冲区的字符串(StringBuffer)写数据。
PipedWriter
连接到一个 PipedReader。
CharArrayWriter
向内存缓冲区的字符数组写数据。
FilterWriter
输出流方法
append(char c) 将参数 c 指定的字符添加到输出流中 append(charSequence esq) 将参数 esq 指定的字符序列添加到输出流中 append(charSequence esq,int start,int end) 将参数 esq 指定的字符序列的子序列添加到输出流中。其中,start 指定 子序列的第一个字符的索引,end 指定子序列中最后一个字符后面的字符 的索引,也就是说子序列的内容包含 start 索引处的字符,但不包括 end 索引处的字符
字节流
InputStream
FileInputStream
从文件中读取数据。
FilterInputStream
BufferedInputStream
DataInputStream
PushbackInputStream
ObjectInputStream
将对象反序列化
PipedInputStream
连接到一个 PipedOutputStream(管道输出流)
SequenceInputStream
将多个字节输入流串联成一个字节输入流。
StringBufferInputStream
ByteArrayInputStream
将字节数组转换为字节输入流,从中读取字节
OutputStream
FileOutputStream
向文件中写数据。
FilterOutputStream
BufferedOutputStream
DataOutputStream
PrintStream
ObjectOutputStream
将对象序列化。
PipedOutputStream
连接到一个 PipedlntputStream(管道输入流)。
byteArrayOutputStream
向内存缓冲区的字节数组中写数据。
字节输入流常用方法
方法名及返回值类型 说明 int read() 从输入流中读取一个 8 位的字节,并把它转换为 0~255 的整数,最后返回整数。 如果返回 -1,则表示已经到了输入流的末尾。为了提高 I/O 操作的效率,建议尽量 使用 read() 方法的另外两种形式 int read(byte[] b) 从输入流中读取若干字节,并把它们保存到参数 b 指定的字节数组中。 该方法返回 读取的字节数。如果返回 -1,则表示已经到了输入流的末尾 int read(byte[] b, int off, int len) 从输入流中读取若干字节,并把它们保存到参数 b 指定的字节数组中。其中,off 指 定在字节数组中开始保存数据的起始下标;len 指定读取的字节数。该方法返回实际 读取的字节数。如果返回 -1,则表示已经到了输入流的末尾 void close() 关闭输入流。在读操作完成后,应该关闭输入流,系统将会释放与这个输入流相关 的资源。注意,InputStream 类本身的 close() 方法不执行任何操作,但是它的许多 子类重写了 close() 方法 int available() 返回可以从输入流中读取的字节数 long skip(long n) 从输入流中跳过参数 n 指定数目的字节。该方法返回跳过的字节数 void mark(int readLimit) 在输入流的当前位置开始设置标记,参数 readLimit 则指定了最多被设置标记的字 节数 boolean markSupported() 判断当前输入流是否允许设置标记,是则返回 true,否则返回 false void reset() 将输入流的指针返回到设置标记的起始处
字节输出流常用方法
方法名及返回值类型 说明 void write(int b) 向输出流写入一个字节。这里的参数是 int 类型,但是它允许使用表达式, 而不用强制转换成 byte 类型。为了提高 I/O 操作的效率,建议尽量使用 write() 方法的另外两种形式 void write(byte[] b) 把参数 b 指定的字节数组中的所有字节写到输出流中 void write(byte[] b,int off,int len) 把参数 b 指定的字节数组中的若干字节写到输出流中。其中,off 指定字节 数组中的起始下标,len 表示元素个数 void close() 关闭输出流。写操作完成后,应该关闭输出流。系统将会释放与这个输出 流相关的资源。注意,OutputStream 类本身的 close() 方法不执行任何操 作,但是它的许多子类重写了 close() 方法 void flush() 为了提高效率,在向输出流中写入数据时,数据一般会先保存到内存缓冲 区中,只有当缓冲区中的数据达到一定程度时,缓冲区中的数据才会被写 入输出流中。使用 flush() 方法则可以强制将缓冲区中的数据写入输出流, 并清空缓冲区
字符流、字节流的区别
读写的时候字节流是按字节读写,字符流按字符读写。
字节流适合所有类型文件的数据传输,因为计算机字节(Byte)是电脑中表示信息含义的最小单位。字符流只能够处理纯文本数据,其他类型数据不行,但是字符流处理文本要比字节流处理文本要方便。
File类
File 类不能访问文件内容本身,如果需要访问文件内容本身,则需要使用输入/输出流。
构造方法
File(String path)
如果 path 是实际存在的路径,则该 File 对象表示的是目录;如果 path 是文件名,则该 File 对象表示的是文件。
File(String Path,String name)
path 是路径名,name 是文件名。
File(File dir, String name)
dir 是路径对象,name 是文件名。
File类常用方法
boolean canRead() 测试应用程序是否能从指定的文件中进行读取 boolean canWrite() 测试应用程序是否能写当前文件 boolean delete() 删除当前对象指定的文件 boolean exists() 测试当前 File 是否存在 String getAbsolutePath() 返回由该对象表示的文件的绝对路径名 String getName() 返回表示当前对象的文件名或路径名(如果是路径,则返回最后一级子路径名) String getParent() 返回当前 File 对象所对应目录(最后一级子目录)的父目录名 boolean isAbsolute() 测试当前 File 对象表示的文件是否为一个绝对路径名。该方法消除了不同平台的差异,可以直接判断 file 对象是否为绝对路径。在 UNIX/Linux/BSD 等系统上,如果路径名开头是一条斜线/,则表明该 File 对象对应一个绝对路径;在 Windows 等系统上,如果路径开头是盘符,则说明它是一个绝对路径。 boolean isDirectory() 测试当前 File 对象表示的文件是否为一个路径 boolean isFile() 测试当前 File 对象表示的文件是否为一个“普通”文件 long lastModified() 返回当前 File 对象表示的文件最后修改的时间 long length() 返回当前 File 对象表示的文件长度 String[] list() 返回当前 File 对象指定的路径文件列表 String[] list(FilenameFilter) 返回当前 File 对象指定的目录中满足指定过滤器的文件列表 boolean mkdir() 创建一个目录,它的路径名由当前 File 对象指定 boolean mkdirs() 创建一个目录,它的路径名由当前 File 对象指定 boolean renameTo(File) 将当前 File 对象指定的文件更名为给定参数 File 指定的路径名
路径分隔符
假设在 Windows 操作系统中有一文件D:\javaspace\hello.java,在 Java 中使用的时候,其路径的写法应该为D:/javaspace/hello.java或者D:\\javaspace\\hello.java
public static final String separator
分隔符常量,解决不同操作系统分隔符不一致的问题,Windows用\,linux用/
创建新文件
createNewFile()
文件类实例对象.createNewFile()
Scanner类
java.util.Scanner
java5新特征
next()
1、一定要读取到有效字符后才可以结束输入。
2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
4、next() 不能得到带有空格的字符串。
nextLine()
1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
2、可以获得空白。
nextxxx()
获取xxx类型的数据
hasNextxxx()
判断输入的类型是否xxx,建议获取值之前先判断
多线程
概念
一条线程指的是进程中一个单一顺序的控制流
线程是进程的一部分,必须等所有线程都结束后进程才能结束
线程的生命周期
新建
使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程
执行start()方法
就绪
当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度
执行run()方法
运行
如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
run()方法执行结束
死亡
一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。
线程的优先级
占位
等级为1(Thread.MIN_PRIORITY),10(Thread.MAX_PRIORITY),默认为NORM_PRIORITY(5)
线程的创建
1、继承THread类
重写run()方法
声明线程类的对象
线程对象.start()
继承类的方式,缺点是不能再继承其他类
2、实现Runnable接口
重写run()方法
声明线程类的对象
创建一个Thread类的对象,构造器参数为实现了Runnable的类的对象
线程对象.start()
3、通过Callable接口和Future创建
1. 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。 2. 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。 3. 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。 4. 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
实现类重写call()方法
将实现类的对象传入FutureTask()构造器中,创建FutureTask的对象
将FutureTask的对象传入线程类的Thread构造器中
线程对象.start()
实现接口方式,可以继承其他类
4、通过线程池创建
提供线程池
ExecutorService service = Executors.newFixedThreadPool(10);
提供run()的实现类对象
线程池对象.execute()
线程池对象.shutdown()
三种方式对比
1. 采用实现 Runnable、Callable 接口的方式创建多线程时,线程类只是实现了 Runnable 接口或 Callable 接口,还可以继承其他类。 2. 使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 即可获得当前线程。
解决线程安全问题
1、同步代码块
synchronized(同步监视器){ }
1、用于处理使用了共享数据的代码
2、同步监视器(锁)可以是任意类的一个对象
3、多个线程必须公用同一把锁
2、同步方法
将操作共享数据的代码放到同一个方法中
将该方法声明为synchronized同步的
例: 修饰符 static|final synchronized 返回值类型 方法名(){}
3、手动上锁
* 把代码块放入try{ * 上锁:lock.lock(); * }finally{ * 解锁:lock.unlock() * }中 *
公平锁ReentrantLock
ReentrantLock lock = new ReentrantLock();
线程通信
class window implements Runnable{ private int number = 100; @Override public void run() { while(true){ synchronized (this) { notifyAll();//唤醒线程 if(number > 0){ System.out.println(Thread.currentThread().getName()+"打印"+number); number--; }else{ break; } try { //阻塞线程,并释放锁 wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
wait()
阻塞线程
notify()
唤醒线程
该方法必须要放在同步代码块中,且调用者必须是同步监视器(this)
反射
概念
编译期:是指把源码交给编译器编译成计算机可以执行的文件的过程。在 Java 中也就是把 Java 代码编成 class 文件的过程。编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而只是把代码当成文本进行操作,比如检查错误。
运行期:是把编译后的文件交给计算机执行,直到程序运行结束。所谓运行期就把在磁盘中的代码放到内存中执行起来。
反射机制:动态获取信息以及动态调用对象方法
可访问的信息
类型 访问方法 返回值类型 说明 包路径 getPackage() Package 对象 获取该类的存放路径 类名称 getName() String 对象 获取该类的名称 继承类 getSuperclass() Class 对象 获取该类继承的类 实现接口 getlnterfaces() Class 型数组 获取该类实现的所有接口 构造方法 getConstructors() Constructor 型数组 获取所有权限为 public 的构造方法 getDeclaredContruectors() Constructor 对象 获取当前对象的所有构造方法 方法 getMethods() Methods 型数组 获取所有权限为 public 的方法 getDeclaredMethods() Methods 对象 获取当前对象的所有方法 成员变量 getFields() Field 型数组 获取所有权限为 public 的成员变量 getDeclareFileds() Field 对象 获取当前对象的所有成员变量 内部类 getClasses() Class 型数组 获取所有权限为 public 的内部类 getDeclaredClasses() Class 型数组 获取所有内部类 内部类的声明类 getDeclaringClass() Class 对象 如果该类为内部类,则返回它的成员类,否则返回 null
Class类
每一种类型包括类和接口等,都有一个 class 静态变量(类.class)可以获得 Class 实例。另外,每一个对象都有 getClass() 方法可以获得 Class 实例,该方法是由 Object 类提供的实例方法。
Class.forName(全类名)
创建某个类的运行时对象
访问构造方法
Constructor类
方法名称 说明 isVarArgs() 查看该构造方法是否允许带可变数量的参数,如果允许,返回 true,否则返回 false getParameterTypes() 按照声明顺序以 Class 数组的形式获取该构造方法各个参数的类型 getExceptionTypes() 以 Class 数组的形式获取该构造方法可能抛出的异常类型 newInstance(Object … initargs) 通过该构造方法利用指定参数创建一个该类型的对象,如果未设置参数则表示 采用默认无参的构造方法 setAccessiable(boolean flag) 如果该构造方法的权限为 private,默认为不允许通过反射利用 netlnstance() 方法创建对象。如果先执行该方法,并将入口参数设置为 true,则允许创建对 象 getModifiers() 获得可以解析出该构造方法所采用修饰符的整数
Modifier类
静态方法名称 说明 isStatic(int mod) 如果使用 static 修饰符修饰则返回 true,否则返回 false isPublic(int mod) 如果使用 public 修饰符修饰则返回 true,否则返回 false isProtected(int mod) 如果使用 protected 修饰符修饰则返回 true,否则返回 false isPrivate(int mod) 如果使用 private 修饰符修饰则返回 true,否则返回 false isFinal(int mod) 如果使用 final 修饰符修饰则返回 true,否则返回 false toString(int mod) 以字符串形式返回所有修饰符
访问方法
Method类
表1 Method类的常用方法 静态方法名称 说明 getName() 获取该方法的名称 getParameterType() 按照声明顺序以 Class 数组的形式返回该方法各个参数的类型 getReturnType() 以 Class 对象的形式获得该方法的返回值类型 getExceptionTypes() 以 Class 数组的形式获得该方法可能抛出的异常类型 invoke(Object obj,Object...args) 利用 args 参数执行指定对象 obj 中的该方法,返回值为 Object 类型 isVarArgs() 查看该方法是否允许带有可变数量的参数,如果允许返回 true,否则返回 false getModifiers() 获得可以解析出该方法所采用修饰符的整数
访问成员变量
Filed类
表1 Field类的常用方法 方法名称 说明 getName() 获得该成员变量的名称 getType() 获取表示该成员变量的 Class 对象 get(Object obj) 获得指定对象 obj 中成员变量的值,返回值为 Object 类型 set(Object obj, Object value) 将指定对象 obj 中成员变量的值设置为 value getlnt(0bject obj) 获得指定对象 obj 中成员类型为 int 的成员变量的值 setlnt(0bject obj, int i) 将指定对象 obj 中成员变量的值设置为 i setFloat(Object obj, float f) 将指定对象 obj 中成员变量的值设置为 f getBoolean(Object obj) 获得指定对象 obj 中成员类型为 boolean 的成员变量的值 setBoolean(Object obj, boolean b) 将指定对象 obj 中成员变量的值设置为 b getFloat(Object obj) 获得指定对象 obj 中成员类型为 float 的成员变量的值 setAccessible(boolean flag) 此方法可以设置是否忽略权限直接访问 private 等私有权限的成员变量 getModifiers() 获得可以解析出该方法所采用修饰符的整数
访问数组
static Object newInstance(Class<?> componentType, int…length)
创建一个具有指定的元素类型、指定维度的新数组
static xxx getXxx(Object array, int index)
返回 array 数组中第 index 个元素,如果数组元素是引用类型,则该方法变为 get(Object array, int index)。
static void setXxx(Object array, int index, xxx val)
将 array 数组中第 index 个元素的值设为 val
访问泛型
Type接口
getGenericType()
获取泛型类型
ParameterizedType类
ParameterizedType 代表被参数化的类型,也就是增加了泛型限制的类型。
getRawType()
返回没有泛型信息的原始类型。
getActualTypeArguments()
返回泛型参数的类型。
注解
概念
1、注解并不能改变程序的运行结果,也不会影响程序运行的性能。有些注解可以在编译时给用户提示或警告,有的注解可以在运行时读写字节码文件信息。
2、注解是一种元数据,用来描述源代码
3、元注解:描述注解的注解
作用
1、生成帮助文档。这是最常见的,也是 Java 最早提供的注解。常用的有 @see、@param 和 @return 等;
2、跟踪代码依赖性,实现替代配置文件功能。比较常见的是 Spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量;
3、在编译时进行格式检查。如把 @Override 注解放在方法前,如果这个方法并不是重写了父类方法,则编译时就能检查出。
分类
普通注解
@Override
Java 中 @Override 注解是用来指定方法重写的,只能修饰方法并且只能用于方法重写,不能修饰其它的元素。它可以强制一个子类必须重写父类方法或者实现接口的方法。
@Deprecated
Java 中 @Deprecated 可以用来注解类、接口、成员方法和成员变量等,用于表示某个元素(类、方法等)已过时。当其他程序使用已过时的元素时,编译器将会给出警告。
@SuppressWarnings
Java 中的 @SuppressWarnings 注解指示被该注解修饰的程序元素(以及该程序元素中的所有子元素)取消显示指定的编译器警告,且会一直作用于该程序元素的所有子元素。例如,使用 @SuppressWarnings 修饰某个类取消显示某个编译器警告,同时又修饰该类里的某个方法取消显示另一个编译器警告,那么该方法将会同时取消显示这两个编译器警告。
例子:定义的变量未使用编译器会给出警告,添加上该注解会取消该警告
抑制警告关键字
关键字 用途 all 抑制所有警告 boxing 抑制装箱、拆箱操作时候的警告 cast 抑制映射相关的警告 dep-ann 抑制启用注释的警告 deprecation 抑制过期方法警告 fallthrough 抑制在 switch 中缺失 breaks 的警告 finally 抑制 finally 模块没有返回的警告 hiding 抑制相对于隐藏变量的局部变量的警告 incomplete-switch 忽略不完整的 switch 语句 nls 忽略非 nls 格式的字符 null 忽略对 null 的操作 rawtypes 使用 generics 时忽略没有指定相应的类型 restriction 抑制禁止使用劝阻或禁止引用的警告 serial 忽略在 serializable 类中没有声明 serialVersionUID 变量 static-access 抑制不正确的静态访问方式警告 synthetic-access 抑制子类没有按最优方法访问内部类的警告 unchecked 抑制没有进行类型检查操作的警告 unqualified-field-access 抑制没有权限访问的域的警告 unused 抑制没被使用过的代码的警告
@SafeVarargs
与@SuppressWarnings类似
注意:@SafeVarargs注解不适用于非 static 或非 final 声明的方法,对于未声明为 static 或 final 的方法,如果要抑制 unchecked 警告,可以使用 @SuppressWarnings 注解。
@FunctionalInterface
@FunctionalInterface 就是用来指定某个接口必须是函数式接口,所以 @FunInterface 只能修饰接口,不能修饰其它程序元素
元注解
@Documented
@Documented 是一个标记注解,没有成员变量。用 @Documented 注解修饰的注解类会被 JavaDoc 工具提取成文档。默认情况下,JavaDoc 是不包括注解的,但如果声明注解时指定了 @Documented,就会被 JavaDoc 之类的工具处理,所以注解类型信息就会被包括在生成的帮助文档中。
@Target
@Target 注解用来指定一个注解的使用范围,即被 @Target 修饰的注解可以用在什么地方。@Target 注解有一个成员变量(value)用来设置适用目标,value 是 java.lang.annotation.ElementType 枚举类型的数组,下表为 ElementType 常用的枚举常量。
范围表
名称 说明 CONSTRUCTOR 用于构造方法 FIELD 用于成员变量(包括枚举常量) LOCAL_VARIABLE 用于局部变量 METHOD 用于方法 PACKAGE 用于包 PARAMETER 用于类型参数(JDK 1.8新增) TYPE 用于类、接口(包括注解类型)或 enum 声明
@Retention
@Retention 用于描述注解的生命周期,也就是该注解被保留的时间长短。@Retention 注解中的成员变量(value)用来设置保留策略,value 是 java.lang.annotation.RetentionPolicy 枚举类型,RetentionPolicy 有 3 个枚举常量,如下所示。
1、SOURCE
在源文件中有效(即源文件保留)
2、CLASS
在 class 文件中有效(即 class 保留)
3、RUNTIME
在运行时有效(即运行时保留)
生命周期排序:SOURCE < CLASS < RUNTIME,前者能使用的地方后者一定也能使用
@Inherited
@Inherited 是一个标记注解,用来指定该注解可以被继承。使用 @Inherited 注解的 Class 类,表示这个注解可以被用于该 Class 类的子类。就是说如果某个类使用了被 @Inherited 修饰的注解,则其子类将自动具有该注解。
@Repeatable
@Repeatable 注解是 Java 8 新增加的,它允许在相同的程序元素中重复注解,在需要对同一种注解多次使用时,往往需要借助 @Repeatable 注解。Java 8 版本以前,同一个程序元素前最多只能有一个相同类型的注解,如果需要在同一个元素前使用多个相同类型的注解,则必须使用注解“容器”。
@Native
使用 @Native 注解修饰成员变量,则表示这个变量可以被本地代码引用,常常被代码生成工具使用。对于 @Native 注解不常使用,了解即可
自定义注解
1、使用@interface 关键字
// 定义一个简单的注解类型 public @interface Test { } public @interface MyTag { // 定义带两个成员变量的注解 // 注解中的成员变量以方法的形式来定义 String name(); int age(); }
2、一个源程序文件中可以声明多个注解,但只能有一个是公有访问权限的注解。且源程序文件命名和公有访问权限的注解名一致。
3、根据需要,注解中可以定义成员变量,成员变量以无形参的方法形式来声明,其方法名和返回值定义了该成员变量的名字和类型
4、注解中的成员变量也可以有默认值,可使用 default 关键字
public @interface MyTag { // 定义了两个成员变量的注解 // 使用default为两个成员变量指定初始值 String name() default "C语言中文网"; int age() default 7; }
通过反射获取注解
方法名 作用 <A extends Annotation> A getAnnotation(Class<A> annotationClass) 如果该元素存在 annotationClass 类型的注解,则返回注解,否则返回 null <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) 这是 Java 8 新增的方法,该方法尝试获取直接修饰该程序元素、指定类型的注解。如果该类型的注解不存在,则返回 null Annotation[] getAnnotations() 返回该元素上存在的所有注解 Annotation[] getDeclaredAnnotations() 返回直接存在于该元素的所有注解(和 getAnnotations() 的区别在于该方法将不返回继承的注释) boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) 判断该元素上是否存在 annotationClass 类型的注解,如果存在则返回 true,否则返回 false。 <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) 该方法与前面介绍的 getAnnotation() 方法基本相似。但由于 Java 8 增加了重复注解功能,因此需要使用该方法获取该元素存在 annotationClass 类型的多个注解。 <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass) 该方法与前面介绍的 getDeclaredAnnotations() 方法基本相似。但由于 Java 8 增加了重复注解功能,因此需要使用该方法获取该元素存在 annotationClass 类型的多个注解。
泛型
概念
1、Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型
2、泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数
实现
泛型集合
List<泛型参数> bookList = new ArrayList<泛型参数>()
泛型类
public class class_name<data_type1,data_type2,…>{}
public class Stu<N, A, S> { private N name; // 姓名 private A age; // 年龄 private S sex; // 性别 // 创建类的构造函数 public Stu(N name, A age, S sex) { this.name = name; this.age = age; this.sex = sex; } }
泛型参数支持一个或多个
一般用于类的属性类型不确定的情况下
泛型方法
[访问权限修饰符] [static] [final] <类型参数列表> 返回值类型 方法名([形式参数列表])
public <T> T getObject(Class<T> c){}
<T>:表面该方法是一个泛型方法
T:表面该方法的返回值是T类型
class<T>:指明T的具体类型
高级用法
1、限制泛型可用类型
<T extends Person>
1、表面T只能是<=Person的类型
2、修饰类:T只能是实现或继承了Person的类型
3、如果没有使用限制符:默认使用Object类<T extends Object>
2、使用类型通配符
泛型类名称<? extends List>a = null;
<? extends List>作为一个整体表示类型未知,当需要使用泛型对象时,可以单独实例化。
3、继承泛型类和实现泛型接口
若子类在继承父类时保留父类的泛型,需要在继承时指定
public class FatherClass<T1>{} public class SonClass<T1,T2,T3> extents FatherClass<T1>{}
4、通用父类
类<?>
类<?>可以是类<A>和类<B>的共同父类,即类<A>和类<B>之间没有父子关系,不能互相赋值
集合
结构图

Map(接口)
是存放一对值的最大接口,即接口中的每个元素都是一对,以 key➡value 的形式保存
AbstractMap(抽象类)
IdentityHashMap(类)
HashMap(类)
按哈希算法来存取键对象
LinkedHashMap(类)
WeakHashMap(类)
Dictionary(类)
非AbstractMap子类,放这里仅为了方便
Hashtable(类)
TreeMap(类)
可以对键对象进行排序
SortedMap(接口)
NavigableMap(接口)
Iterator(接口)
集合对象想要迭代,就必须要使用迭代器,实现Iterable接口
Iterable(接口)
封装了Iterator接口 为什么不直接继承Iterator接口: 可以保证每个对象调用一次Iterator方法,返回的是一个新的迭代器对象
Collection(接口)
Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, Java不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。
AbstractCollection(抽象类)
AbstractList(抽象类)
Vector(类)
Stack(类)
ArrayList(类)
一个用数组实现的 List,能进行快速的随机访问,效率高而且实现了可变大小的数组
AbstractSequentialList(抽象类)
LinkedList(类)
对顺序访问进行了优化,但随机访问的速度相对较慢。此外它还有 addFirst()、addLast()、getFirst()、getLast()、removeFirst() 和 removeLast() 等方法,能把它当成栈(Stack)或队列(Queue)来用
List(接口)
是最常用的接口。是有序集合,允许有相同的元素。使用 List 能够精确地控制每个元素插入的位置,用户能够使用索引(元素在 List 中的位置,类似于数组下标)来访问 List 中的元素,与数组类似。
Set(接口)
不能包含重复的元素。
AbstractSet(抽象类)
继承了AbstractCollection接口 实现了Set接口,并重写了Set的部分方法
HashSet(类)
为优化査询速度而设计的 Set。它是基于 HashMap 实现的,HashSet 底层使用 HashMap 来保存所有元素,实现比较简单
LinkedHashSet(类)
TreeSet(类)
实现了 Set 接口,是一个有序的 Set,这样就能从 Set 里面提取一个有序序列
SortedSet(接口)
NavigableSet(接口)
Queue(接口)
Queue 是 Java 提供的单向队列实现,有点类似于 List。
Deque(接口)
是 Queue 的一个子接口,为双向队列。
ArrayDeque(类)
是一个基于数组实现的双端队列,按“先进先出”的方式操作集合元素
LinkIterator(接口)(暂未找到相关资料)
Collection接口
一般不直接继承或实现,通常使用List或者Set等等
常用方法
boolean add(E e): 向集合中添加一个元素,如果集合对象被添加操作改变了,则返回true,E是元素的数据类型 boolean addAll(Collection c): 向集合中添加集合c中的所有元素,添加成功,返回true void clear(): 清除集合中的所有元素,将集合长度变为0; boolean contains(Object o): 判断集合中是否包含指定元素 boolean containsAll(Collection c): 判断集合中是否包含集合c的所有元素 boolean isEmpty(): 判断集合是否为空 Iterator<E> iterator(): 返回一个Iterator对象,用于遍历集合中的所有元素 boolean remove(Object o): 从集合中删除一个制定元素,当集合中包含了一个或多个元素o时,删除第一个o,返回true boolean removeAll(Collection c): 从集合中删除c中出现的所有元素,相当于作差集A-B,若A改变了,返回true boolean retainAll(Collection c): 从集合中删除c里不包含的元素,相当于作交集A∩B,A改变,返回true int size(): 返回集合中元素的个数
若需要遍历集合中的元素,需使用迭代器
List接口
一个有序的、可重复的集合,可通过索引访问集合中的元素,索引值与元素的添加顺序有关
实现类
ArrayList
特点
底层采用数组存储数据,实现了数组的可变,自动扩容
由于是像数组一样按索引操作元素,所以插入和删除元素速度较慢,但随机访问元素的速度较快
初始容量:10
构造器
ArrayList()
创建一个初始容量为10的空集合
ArrayList(Collection<?extends E>c)
构造一个包含指定 Collection 元素的列表,这些元素是按照该 Collection 的迭代器返回它们的顺序排列的。
常用方法
1、Collection的所有方法
2、新增方法
E get(int index): 获取此集合中指定索引位置的元素 int index(Object o): 返回集合中第一次出现指定元素o的索引,如果未找到,返回-1 int lastIndex(Object o): 最后一次出现指定元素o的索引 E set(int index,Element): 将集合中指定索引位置的元素修改为element,并返回原元素 List<E> subList(int fromIndex,int toIndex): 返回一个新集合。内容为:fromIndex到toIndex之间的所有元素,左闭右开
LinkedList
特点
底层采用链表存储数据,便于插入或删除元素
插入和删除元素速度快,但随机访问元素的速度较慢
构造器
与ArrayList一致
常用方法
1、Collection的所有方法
2、新增方法
void addFirst(E e): 降指定元素添加到此集合的开头(头插法) void addLast(E e): 将指定元素添加到此集合的结尾(尾插法) E getFirst(): 获取集合的第一个元素 E getLast(): 获取集合的最后一个元素 E removeFirst(): 删除集合中的第一个元素 E removeLast(): 删除集合中的最后一个元素
ArrayList和LinkedList的区别
参考各自特点
Set接口
不按特定的顺序存储数据,元素不可重复,最多只能包含一个null
实现类
HashSet
特点
1、按照hash算法来存储数据,有着很好的查找和存取性能
2、不能保证存取元素的顺序
3、HashSet线程不安全,如果有多个线程同时访问或修改同一个HashSet,需要线程同步
4、存取顺序:先比较哈希值,如果哈希值相等,则再equals(),都为true才添加成功
5、后添加的元素会覆盖先添加的元素
构造方法
HashSet()
HashSet(Collection<? extends E>c)
常用方法
Collection的所有方法
LinkedHashSet
遍历时,可以按照添加的顺序遍历,同时维护了两个引用,记录前一个和后一个数据
特点
频繁的插入操作效率高
TreeSet
特点
1、实现了SortedSet和Set,可以对集合进行自然(升序)排序,只能对实现了Comparable接口的集合进行排序
构造方法
同上
常用方法
1、Collection的所有方法
2、新增方法
E first(): 返回此集合中的第一个元素 E last(): 返回此集合中的最后一个元素 E poolFirst(): 获取并移除此集合中的第一个元素 E poolLast(): 获取并移除此集合中的最后一个元素 SortedSet<E> subSet(E fromElement, E toElement): 返回一个新集合,内容为从fromElement到toElement之间的所有对象,左闭右开 SortedSet<E> headSet(E toElement): 返回一个新集合,内容为toElement之前的所有对象,不包含 Sorted<E> tailSet(E fromElement): 返回一个新集合,内容为fromElement之后的所有对象,包含
Map接口
特点
Map 是一种键-值对(key-value)集合,Map 集合中的每一个元素都包含一个键(key)对象和一个值(value)对象。用于保存具有映射关系的数据
1、Key不允许重复,vaule可以重复
2、由1可知,Key用Set存储,Value用Collection存储
3、values所在的类需要重写hashcode()和equals()方法
Map接口常用方法
方法名称 说明 void clear() 删除该 Map 对象中的所有 key-value 对。 boolean containsKey(Object key) 查询 Map 中是否包含指定的 key,如果包含则返回 true。 boolean containsValue(Object value) 查询 Map 中是否包含一个或多个 value,如果包含则返回 true。 V get(Object key) 返回 Map 集合中指定键对象所对应的值。V 表示值的数据类型 V put(K key, V value) 向 Map 集合中添加键-值对,如果当前 Map 中已有一个与该 key 相等的 key-value 对,则新的 key-value 对会覆盖原来的 key-value 对。 void putAll(Map m) 将指定 Map 中的 key-value 对复制到本 Map 中。 V remove(Object key) 从 Map 集合中删除 key 对应的键-值对,返回 key 对应的 value,如果该 key 不存在,则返回 null boolean remove(Object key, Object value) 这是 Java 8 新增的方法,删除指定 key、value 所对应的 key-value 对。如果从该 Map 中成功地删除该 key-value 对,该方法返回 true,否则返回 false。 Set entrySet() 返回 Map 集合中所有键-值对的 Set 集合,此 Set 集合中元素的数据类型为 Map.Entry Set keySet() 返回 Map 集合中所有键对象的 Set 集合 boolean isEmpty() 查询该 Map 是否为空(即不包含任何 key-value 对),如果为空则返回 true。 int size() 返回该 Map 里 key-value 对的个数 Collection values() 返回该 Map 里所有 value 组成的 Collection
JDK8新增方法
名称 说明 Object compute(Object key, BiFunction remappingFunction) 该方法使用 remappingFunction 根据原 key-value 对计算一个新 value。只要新 value 不为 null,就使用新 value 覆盖原 value;如果原 value 不为 null,但新 value 为 null,则删除原 key-value 对;如果原 value、新 value 同时为 null,那么该方法不改变任何 key-value 对,直接返回 null。 Object computeIfAbsent(Object key, Function mappingFunction) 如果传给该方法的 key 参数在 Map 中对应的 value 为 null,则使用 mappingFunction 根据 key 计算一个新的结果,如果计算结果不为 null,则用计算结果覆盖原有的 value。如果原 Map 原来不包括该 key,那么该方法可能会添加一组 key-value 对。 Object computeIfPresent(Object key, BiFunction remappingFunction) 如果传给该方法的 key 参数在 Map 中对应的 value 不为 null,该方法将使用 remappingFunction 根据原 key、value 计算一个新的结果,如果计算结果不为 null,则使用该结果覆盖原来的 value;如果计算结果为 null,则删除原 key-value 对。 void forEach(BiConsumer action) 该方法是 Java 8 为 Map 新增的一个遍历 key-value 对的方法,通过该方法可以更简洁地遍历 Map 的 key-value 对。 Object getOrDefault(Object key, V defaultValue) 获取指定 key 对应的 value。如果该 key 不存在,则返回 defaultValue。 Object merge(Object key, Object value, BiFunction remappingFunction) 该方法会先根据 key 参数获取该 Map 中对应的 value。如果获取的 value 为 null,则直接用传入的 value 覆盖原有的 value(在这种情况下,可能要添加一组 key-value 对);如果获取的 value 不为 null,则使用 remappingFunction 函数根据原 value、新 value 计算一个新的结果,并用得到的结果去覆盖原有的 value。 Object putIfAbsent(Object key, Object value) 该方法会自动检测指定 key 对应的 value 是否为 null,如果该 key 对应的 value 为 null,该方法将会用新 value 代替原来的 null 值。 Object replace(Object key, Object value) 将 Map 中指定 key 对应的 value 替换成新 value。与传统 put() 方法不同的是,该方法不可能添加新的 key-value 对。如果尝试替换的 key 在原 Map 中不存在,该方法不会添加 key-value 对,而是返回 null。 boolean replace(K key, V oldValue, V newValue) 将 Map 中指定 key-value 对的原 value 替换成新 value。如果在 Map 中找到指定的 key-value 对,则执行替换并返回 true,否则返回 false。 replaceAll(BiFunction function) 该方法使用 BiFunction 对原 key-value 对执行计算,并将计算结果作为该 key-value 对的 value 值。
遍历
1、for循环中使用entry遍历
public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("Java入门教程", "http://c.biancheng.net/java/"); map.put("C语言入门教程", "http://c.biancheng.net/c/"); for (Map.Entry<String, String> entry : map.entrySet()) { String mapKey = entry.getKey(); String mapValue = entry.getValue(); System.out.println(mapKey + ":" + mapValue); } }
2、使用 for-each 循环遍历 key 或者 values,一般适用于只需要 Map 中的 key 或者 value 时使用。性能上比 entrySet 较好
Map<String, String> map = new HashMap<String, String>(); map.put("Java入门教程", "http://c.biancheng.net/java/"); map.put("C语言入门教程", "http://c.biancheng.net/c/"); // 打印键集合 for (String key : map.keySet()) { System.out.println(key); } // 打印值集合 for (String value : map.values()) { System.out.println(value); }
3、使用迭代器(Iterator)遍历
Map<String, String> map = new HashMap<String, String>(); map.put("Java入门教程", "http://c.biancheng.net/java/"); map.put("C语言入门教程", "http://c.biancheng.net/c/"); Iterator<Entry<String, String>> entries = map.entrySet().iterator(); while (entries.hasNext()) { Entry<String, String> entry = entries.next(); String key = entry.getKey(); String value = entry.getValue(); System.out.println(key + ":" + value); }
4、通过键找值遍历,这种方式的效率比较低,因为本身从键取值是耗时的操作。
for(String key : map.keySet()){ String value = map.get(key); System.out.println(key+":"+value); }
实现类
HashMap
特点
1、默认大小:16
2、加载因子:0.75f
3、扩容:2倍
4、临界值(超过12就扩容):16*0.75=12
5、HashMap采用哈希算法来存取键对象
6、线程不安全,效率高
LiknedHashMap
类似HashMap,保证遍历map时,可以按照保存的顺序遍历,在原有的基础上,添加了2个指针,指向前一个和后一个元素,对于频繁的遍历操作时使用,效率高
HashTable
特点
1、线程安全,效率低
TreeMap
特点
Treemap可以对键对象进行排序
Collections工具类
排序(正向和逆向)
void reverse(List list): 对指定List集合元素进行翻转 void shuffle(List list): 将list集合进行随机排序("洗牌") void sort(List list): 将list集合进行升序排序 void sort(List list,Comparator c): 将list集合进行排序,规则自定 void swap(List list,int i, int j): 将集合中的i和j交换位置 void rotate(List list,int distance): 当distance为正数时,将list集合的后distance个元素“整体”移到前面; 当distance为负数时,将list集合的前distance个元素移到后面。集合list的长度不变
查找、替换操作
int binarySearch(List list,Object key): 使用二分法搜索list(必须有序),获取key在集合中的索引位置 Object max(Collection coll): 根据元素的自然排序,获取最大值 Object max(Collection coll, Comparator comp): 根据指定排序规则的顺序,获取最大值 Object min(Collection coll): 根据自然顺序,获取最小值 Object min(Collection coll,Comparator comp): 根据指定排序规则的顺序,获取最小值 void fill(List list,Object obj): 使用obj替换集合中的所有元素 int frequency(Collection c,Object o): 返回集合中o出现的次数 int indexOfSubList(List source,List target): 返回List对象target在source对象中第一次出现的位置索引。 int lastIndexOfSubList(List source,List target): 类似上一条,最后一次出现的索引位置 boolean replaceAll(List list,Object oldVal,Object newVal): 使用一个新值newVal替换list集合中的所有旧值oldVal
复制
void copy(List <? super T> dest,List<? extends T> src)
将集合src中的元素复制到集合dest中,从索引0位置处开始覆盖,不会改变集合dest的长度
lambda表达式
类和对象
封装
减少代码的耦合性
增加代码的安全性
流程
对外隐藏类的属性,提供相应的方法供外部调用
继承
格式
class father{ } class son extends father{ }
子类拥有父类的非private属性和方法,并且可以有自己的属性和方法
减少代码的重复,提高了类之间的耦合性
java支持单继承、多重继承、多实现
super
实现对当前对象的父类成员的访问
用于调用父类中被子类重写的方法
this
指向当前对象
final
修饰类,则不能被继承
修饰方法,则不能被重写
构造器
子类不继承父类的构造器,只是显式或隐式的调用,如果父类没有空参构造器,则子类需要显式的使用super()调用父类的构造器
多态

多态是同一个行为具有多个不同表现形式或形态的能力。
典型
Parent p = new Child();
接口制定标准
子类实现
重载和重写
重写(Override)
外壳不变,核心重写
子类只能抛出比父类(抛出的异常)小的异常
编译看左边,运行看右边
Parent p = new Child();
重写的规则
参数列表与被重写方法的参数列表必须完全相同 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。 父类的成员方法只能被它的子类重写。 声明为 final 的方法不能被重写。 声明为 static 的方法不能被重写,但是能够被再次声明。 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。 构造方法不能被重写。 如果不能继承一个类,则不能重写该类的方法。
参数列表与被重写方法的参数列表必须完全相同
访问权限不能比父类中被重写的方法的访问权限更低。
声明为 static 的方法不能被重写,但是能够被再次声明(重定义)。
重载(Overload)
方法名字相同,而参数不同。返回类型可以相同也可以不同。
无法以返回值类型作为重载函数的区分标准。
区别
区别点 重载方法 重写方法 参数列表 必须修改 一定不能修改 返回类型 可以修改 一定不能修改 异常 可以修改 可以减少或删除,一定不能抛出新的或者更广的异常 访问 可以修改 一定不能做更严格的限制(可以降低限制) 
抽象类(Abstract)
1. 抽象类不能被实例化
2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
3. 抽象类中的抽象方法只是声明,不包含方法体
4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法
5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类
接口(Interface)
没有构造方法
不能有静态方法
接口中的所有方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。
方法
唯一修饰符:public abstract
变量
唯一修饰符:public static final
枚举类(enum)
JDK5.0之前,需要自定义枚举类
class Season{ private final String season; private final String Desc; 2、// 私有化类的构造器 private Season(String season,String Desc){ this.season=season; this.Desc=Desc; } //3、提供当前类的多个对象 public static final Season Spring = new Season("春天","春天的描述"); }
JDK5.0,可以使用enum来声明枚举类
enum Season{ //3、提供当前类的多个对象 Spring("春天","春天的描述"), Spring("春天","春天的描述"), Spring("春天","春天的描述"); //1、声明私有化变量 private final String season; private final String Desc; 2、// 私有化类的构造器 private Season(String season,String Desc){ this.season=season; this.Desc=Desc; } }
多个的对象之间用逗号分隔,最后分号结束
因为继承的Enum父类,可以不重写toString,直接打印会显示常量名
实现接口,每个常量对象可以使用匿名内部类分别实现接口方法
枚举类方法
values() 返回枚举类中所有的值(常量值)。 ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样。 valueOf()方法返回指定字符串值的枚举常量(一个对象)。
包
类文件的路径
包名/类
例如,一个Something.java 文件它的内容 package net.java.util; public class Something{ ... }
避免类名冲突
同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别
需要使用某包下的类时,必须先导入该包
例子
java.lang-打包基础的类
java.io-包含输入输出功能的函数
import关键字
导入需要的类
异常处理
Exception类结构
Throwable
Error
OutOfMemoryError
IOError
Exception
IOException
FileNotFoundException
RuntimeException
NullPointerException
异常方法
序号 方法及说明 1 public String getMessage() 返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。 2 public Throwable getCause() 返回一个Throwable 对象代表异常原因。 3 public String toString() 使用getMessage()的结果返回类的串级名字。 4 public void printStackTrace() 打印toString()结果和栈层次到System.err,即错误输出流。 5 public StackTraceElement [] getStackTrace() 返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。 6 public Throwable fillInStackTrace() 用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。
捕获异常
try...catch
抛出异常
throws
放在方法尾部,抛出异常
throw
手动抛出异常对象
自定义异常
class MyException extends Exception{ }
正则表达式
// 将一个字符串编译成 Pattern 对象 Pattern p = Pattern.compile("a*b"); // 使用 Pattern 对象创建 Matcher 对象 Matcher m = p.matcher("aaaaab"); boolean b = m.matches(); // 返回 true
Pattern 类
pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数
Matcher 类
Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象
常用方法
表 1 Matcher 类的几个常用方法 名称 说明 find() 返回目标字符串中是否包含与 Pattern 匹配的子串 group() 返回上一次与 Pattern 匹配的子串 start() 返回上一次与 Pattern 匹配的子串在目标字符串中的开始位置 end() 返回上一次与 Pattern 匹配的子串在目标字符串中的结束位置加 1 lookingAt() 返回目标字符串前面部分与 Pattern 是否匹配 matches() 返回整个目标字符串与 Pattern 是否匹配 reset() 将现有的 Matcher 对象应用于一个新的字符序列。
正则表
合法字符
特殊字符
预定义字符
方括号表达式
边界匹配符
数量表示符
可用stop与destroy函数强行终止
线程阻塞,让出cpu资源
系统调度,获取cpu资源
阻塞
如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种: 等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。 同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。 其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。