我是Java两年开发的农民工、今天总结了Java所有核心类库助你提高Java水平。
文章目录
- Java核心类库
-
- 常用类的概述和使用
- String类的概述和使用
- 可变字符串类和日期相关类
- 集合类库
- 异常机制和File类
- IO流
-
- IO流的概念
- 基本分类
- 体系结构
- 相关流的详解
- 多线程
- 网络编程
- 反射机制
Java核心类库
常用类的概述和使用
常用的包
包的名称和功能
- java.lang包:Java语言的核心包,并且该包中的所有内容由Java虚拟机自动导入。如:System类、String类…
- java.util包:Java语言的工具包,里面提供了大量工具类以及集合类等。如:Scanner类、Random类、List集合…
- java.io包:Java语言中的输入输出包,里面提供了大量读写文件相关的类等。如:FileInputStream类、FileOutputStream类…
- java.net包:Java语言中的网络包,里面提供了大量网络编程相关的类等。如:ServerSocket类、Socket类…
- java.sql包:Java语言中的数据包,里面提供了大量操作数据库的类和接口等。如:DriverManager类、Connection接口…
- Java程序员在编程时可以使用大量类库,因此Java编程需要记得很多
Object类的概述
基本概念
- java.lang.Object类是Java语言中类层级结构的根类,任何一个类都是该类的直接或者间接子类
- 如果定义一个Java类时没有使用extends关键字声明其父类,则其父类为java.lang.Object类
- Object类定义了“对象”的基本行为,被子类默认继承
常用方法
方法声明 | 功能介绍 |
---|---|
Object() | 使用无参方式构造对象 |
boolean equals(Object obj) | 用于判断调用对象是否与参数对象相等。该方法默认比较两个对象的地址是否相等,与==运算符的结果一致。若希望比较两个对象的内容,则需要重写该方法。若该方法被重写后,则应该重写hashCode方法来保证结果的一致性 |
int hashcode() | 用于获取调用对象的哈希值(内存地址编号)。若两个对象调用equals方法相等,则各自调用该方法的结果必须相同。若两个调用对象equals方法不相等,则各自调用该方法的结果应该不相同。为了使得该方法与equals方法保持一致,需要重写该方法。 |
String toString() | 用于获取调用对象的字符串形式。该方法默认返回的字符串为:包名.类名@哈希值的十六进制。为了返回更有意义的数据,需要重写该方法。 |
Class<?> getClass() | 用于返回调用对象执行时的Class实例,反射机制使用 |
包装类
包装类的概念
通常情况下基本数据类型的变量不是对象,为了满足万物皆对象的理念就需要对基本数据类型的变量进行打包封装处理变成对象,而负责将这些变量声明为成员变量进行对象化处理的相关类,叫做包装类。
包装类的分类
包装类 | 对应的基本数据类型 |
---|---|
java.lang.Byte | byte |
java.lang.Short | short |
java.lang.Integer | int |
java.lang.Long | long |
java.lang.Float | float |
java.lang.Double | double |
java.lang.Boolean | boolean |
java.lang.Character | char |
Integer类的概述
java.lang.Integer类内部包装了一个Int类型的变量作为成员变量,主要用于实现对int类型的包装并提供int类型到String类之间的转换等方法。
常用的常量
常量类型和名称 | 功能介绍 |
---|---|
public static final int MAX_VALUE | 表示int类型可以描述的最大值,即2^31 - 1 |
public static final int MIN_VALUE | 表示int类型可以描述的最小值,即-2^31 |
public static final int SIZE | 表示int类型采用二进制补码形式的位数 |
public static final int BYTES | 表示int类型所占的字节个数 |
public static final Class TYPE | 表示int类型的Class实例 |
常用的方法
方法声明 | 功能介绍 |
---|---|
Integer(int value) | 根据参数指定的整数来构造对象(已过时) |
Integer(String s) | 根据参数指定的字符串来构造对象(已过时) |
int intValue() | 获取调用对象中的整数值并返回 |
static Integer valueOf(int i) | 根据参数指定数值得到Integer类型对象 |
boolean equals(Object obj) | 比较调用对象与参数指定的对象是否相等 |
String toString() | 返回描述调用对象数值的字符串形式 |
static int parseInt(String s) | 将字符串类型转换为int类型并返回 |
static String toString(int i) | 获取参数指定整数的十进制字符串形式 |
static String toBinaryString(int i) | 获取参数指定整数的二进制字符串形式 |
static String toHexString(int i) | 获取参数指定整数的十六进制字符串形式 |
static String toOctalString(int i) | 获取参数指定整数的八进制位字符串形式 |
Double类的概述
java.lang.Double类型内部包装了一个double类型的变量作为成员变量,主要用于实现对double类型的包装并提供double类型到String类之间的转换等方法。
常用的常量
常量类型和名称 | 功能介绍 |
---|---|
public static final int SIZE | 表示double类型的二进制位数 |
public static final int BYTES | 表示double类型的字节个数 |
public static final Class TYPE | 表示double类型的Class实例 |
常用的方法
方法声明 | 功能介绍 |
---|---|
Double(double value) | 根据参数指定的浮点数局来构造对象(已过时) |
Double(String s) | 根据参数指定的字符串来构造对象(已过时) |
double doubleValue() | 获取调用对象中的浮点数据并返回 |
static Double valueOf(double d) | 根据参数指定浮点数据得到Double类型对象 |
boolean equals(Object obj) | 比较调用对象与参数指定的对象是否相等 |
String toString() | 返回描述调用对象熟知的字符串形式 |
static dobule parseDouble(String s) | 将字符串类型转换为double类型并返回 |
boolean isNaN() | 判断调用对象的数值是否为数字 |
- java.lang.Number类是个抽象类,是上述类的父类来描述所有类共有的成员
Boolean类的概述
java.lang.Boolean类型内部包装了一个boolean类型的变量作为成员变量,主要用于实现对boolean类型的包装并提供boolean类型到String类之间的转换等方法。
常用的常量
常量类型和名称 | 功能介绍 |
---|---|
public static final Boolean FALSE | 对应基值为false的对象 |
public static final Boolean TRUE | 对应基值为true的对象 |
public static final Class TYPE | 表示boolean类型的Class实例 |
常用的方法
方法声明 | 功能介绍 |
---|---|
Boolean(boolean value) | 根据参数指定的布尔值来构造对象(已过时) |
Boolean(String s) | 根据参数指定的字符串来构造对象(已过时) |
boolean booleanValue() | 获取调用对象的布尔值并返回 |
static Boolean valueOf(boolean b) | 根据参数指定布尔值得到Boolean类型对象 |
boolean equals(Object obj) | 比较调用对象与指定参数的对象是否相等 |
String toString() | 返回描述调用对象数值的字符串形式 |
static boolean parseBoolean(String s) | 将字符串类型转换为boolean类型并返回 |
Character类的概述
java.lang.Character类型内部保重了一个char类型的变量作为成员变量,主要用于实现对char类型的包装并提供字符类别的判断和转换等方法。
常用的常量
常量类型和名称 | 功能介绍 |
---|---|
public static final int SIZE | 表示char类型的二进制位数 |
public static final int BYTES | 表示char类型的字节个数 |
public static final Class TYPE | 表示char类型的Class实例 |
常用的方法
方法声明 | 功能介绍 |
---|---|
Character(char value) | 根据参数指定的字符数来构造对象(已过时) |
char charValue() | 获取调用对象中的字符数据并返回 |
static Character valueOf(char c) | 根据参数指定字符数据得到Character类型对象 |
boolean equals(Object obj) | 比较调用对象与参数指定的对象是否相等 |
String toString() | 返回描述调用对象数值的字符串形式 |
static boolean isUpperCase(char ch) | 判断参数指定字符是否为大写字符 |
static boolean isLowerCase(char ch) | 判断参数指定字符是否为小写字符 |
static boolean isDigit(char ch) | 判断参数指定字符是否为数字字符 |
static char toUpperCase(char ch) | 将参数指定的字符转换为大写字符 |
static char toLowerCase(char ch) | 将参数指定的字符转换为小写字符 |
装箱和拆箱的概念
在Java5发布之前使用包装类对象进行运算时,需要较为繁琐的“拆箱”和“装箱”操作:即运算前先将包装类对象拆分成基本类型数据,运算后再将结果封装成包装类对象。从Java5开始增加了自动拆箱和自动装箱功能。
自动装箱池
在Integer类的内部提供了自动装箱池技术,将-128到127之间的整数已经装箱完毕,当程序中使用该范围内的整数时,无需装箱直接取用自动装箱池中的对象即可,从而提高效率。
包装类(Wrapper)的使用总结
-
基本数据类型转换为对应包装类的方式
调用包装类的构造方法或静态方法即可
-
获取包装类对象中基本数据类型变量数值的方式
调用包装类中的xxxValue方法即可
-
字符串转换为基本数据类型的方式
调用包装类中的parseXxx方法即可
数学处理类
java.lang.Math类主要用于提供执行数学运算的方法,如:对数、平方根
常用的方法
方法声明 | 功能介绍 |
---|---|
static int max(int a, int b) | 返回两个参数中的最大值 |
static int min(int a, int b) | 返回两个参数中的最小值 |
static double pow(double a, double b) | 返回第一个参数的幂 |
static int abs(int a) | 返回参数指定数值的绝对值 |
static long round(double a) | 返回参数四舍五入的结果 |
static double sqrt(double a) | 返回参数的平方根 |
static double random() | 返回0.0到1.0的随机数 |
BigDecimal类的概述
由于float类型和double类型在运算时可能会有误差,若希望实现精确运算则借助java.math.BigDecimal类型加以描述。
常用的方法
方法声明 | 功能介绍 |
---|---|
BigDecimal(String val) | 根据参数指定的字符串来构造对象(推荐) |
BigDecimal add(BigDecimal augend) | 用于实现加法运算 |
BigDecimal subtract(BigDecimal subtrahend) | 用于实现减法运算 |
BigDecimal multiply(BigDecimal multiplicand) | 用于实现乘法运算 |
BigDecimal divide(BigDecimal divisor) | 用于实现除法运算 |
BigInteger类的概念
若希望表示比long类型范围还大的整数数据,则需要借助java.math.BigInteger类型描述。
常用的方法
方法声明 | 功能介绍 |
---|---|
BigInteger(String val) | 根据参数指定的字符串来构造对象 |
BigInteger add(BigInteger val) | 用于实现加法运算 |
BigInteger subtract(BigInteger val) | 用于实现减法运算 |
BigInteger multiply(BigInteger val) | 用于实现乘法运算 |
BigInteger divide(BigInteger val) | 用于实现除法运算 |
BigInteger remainder(BigInteger val) | 用于实现取余运算 |
BigInteger[] divideAndRemainder(BigInteger val) | 用于实现商和余数的运算 |
String类的概述和使用
String类的概念
- java.lang.String类用于描述字符串,Java程序中所有的字符串字面值都可以使用该类的对象加以描述
- 该类由final关键字修饰,表示该类不能被继承
- 从JDK1.9开始该类的底层不使用char[]来存储数据,而是改成byte[]加上编码标记,从而节约了一些空间
- 该类描述的字符串内容是个常量不可更改,因此可以被共享使用
常量池的概念
- 由于String类型描述的字符串内容是常量不可改变,因此Java虚拟机将首次出现的字符串放入常量池中,若后续代码中出现了相同字符串内容则直接使用池中已有的字符串对象而无需申请内存及创建对象,从而提高了性能。
- 常量有优化机制,变量没有
常用的构造方法
方法声明 | 功能介绍 |
---|---|
String() | 使用无参方式构造对象得到空字符序列 |
String(byte[] bytes, int offset, int length) | 使用bytes数组中下标从offset位置开始的length个字节来构造对象 |
String(byte[] bytes) | 使用bytes数组中的所有内容构造对象 |
String(char[] value, int offset, int count) | 使用value数组中下标从offset位置开始的count个字符来构造对象 |
String(char[] value) | 使用value数组中的所有内容构造对象 |
String(String original) | 根据参数指定的字符串内容来构造对象,新创建对象为参数对象的副本 |
常用的成员方法
方法表明 | 功能介绍 |
---|---|
String toString() | 返回字符串本身 |
byte[] getBytes() | 将当前字符串内容转换为byte数组并返回其ASCII值 |
char[] toCharArray() | 用于将当前字符串内容转换为char数组并返回 |
char charAt(int index) | 方法charAt用于返回字符串指定位置的字符 |
int length() | 返回字符串字符序列的长度 |
boolean isEmpty() | 判断字符串是否为空 |
int compareTo(String anotherString) | 用于比较调用对象和参数对象的大小关系 |
int compareToCase(String str) | 不考虑大小写,也就是‘a’和‘A’是相等的关系 |
方法声明 | 功能介绍 |
---|---|
String concat(String str) | 用于实现字符串的拼接 |
boolean contains(CharSequence s) | 用于判断当前字符串是否包含参数指定的内容 |
String toLowerCase() | 返回字符串的小写形式 |
String toUpperCase() | 返回字符串的大写形式 |
String trim() | 返回去掉前导和后继空白的字符串 |
boolean startsWith(String prefix) | 判断字符串是否以参数字符串开头 |
boolean startsWith(String prefix, int toffset) | 从指定位置开始是否以参数字符串开头 |
boolean endsWith(String suffix) | 判断字符串是否以参数字符串结尾 |
方法声明 | 功能介绍 |
---|---|
boolean equals(Object anObject) | 用于比较字符串内容是否相等并返回 |
int hashCode() | 获取调用对象的哈希值 |
boolean equalsIgnoreCase(String anotherString) | 用于比较字符串内容是否相等并返回,不考虑大小写 |
方法声明 | 功能介绍 |
---|---|
int indexOf(int ch) | 用于返回当前字符串中参数ch指定的字符第一次出现的下标 |
int indexOf(int ch, int fromIndex) | 用于从fromIndex位置开始查找ch指定的字符 |
int indexOf(String str) | 在字符串中检索str返回其第一次出现的位置,若找不到返回-1 |
int indexOf(String str, int fromIndex) | 表示从字符串的fromIndex位置开始检索str第一次出现的位置 |
int lastIndexOf(int ch) | 用于返回参数ch指定的字符最后一次出现的下标 |
int lastIndexOf(int ch, int fromIndex) | 用于从fromIndex位置开始查找ch指定字符出现的下标 |
int lastIndexOf(String str) | 返回str指定字符串最后一次出现的下标 |
int lastIndexOf(String str, int fromIndex) | 用于从fromIndex位置开始反向搜索的第一次出现的下标 |
方法声明 | 功能介绍 |
---|---|
String substring(int beginIndex, int endIndex) | 返回字符串中从下标beginIndex(包括)开始到endIndex(不包括)结束的子字符串 |
String substring(int beginIndex) | 返回字符串中从下标beginIndex(包括)开始到字符串结尾的子字符串 |
在使用方法时,千万要小心空指针异常,尽量使用常量.equals(“”)这种格式
正则表达式的概念
- 正则表达式本质就是一个“规则字符串”,可以用于对字符串数据的格式进行验证,以及匹配、查找、匹配等操作。该字符串通常使用^运算符作为开头标志,使用$运算符作为结尾标志,当然也可以省略
正则表达式的规则
正则表达式 | 说明 |
---|---|
[abc] | 可以出现a、b、c中任意一个字符 |
[^abc] | 可以出现除了a、b、c的任意字符 |
[a-z] | 可以出现a、…、z中的任意一个字符 |
[a-zA-Z0-9] | 可以出现a~z、A~Z、0~9中任意一个字符 |
正则表达式 | 说明 |
---|---|
. | 任意一个字符(通常不包含换行符) |
\d | 任意一个个位数字字符 |
\D | 任意一个非数字字符 |
\s | 空白字符,相当于[\t\n\x0B\f\r] |
\S | 非空白字符 |
\w | 任意一个单词字符,相当于[a-zA-Z0-9] |
\W | 任意一个非单词字符 |
正则表达式X | 说明 |
---|---|
X? | 表示X可以出现一次或一次也没有 |
X* | 表示X可以出现零次或多次 |
X+ | 表示X可以出现一次或多次 |
X{n} | 表示X可以出现恰好n次 |
X{n,} | 表示X可以出现至少n次,也就是>=n次 |
X{n, m} | 表示X可以出现至少n次,但是不超过m次 |
正则表达式相关的方法
方法名称 | 方法说明 |
---|---|
boolean matches(String regex) | 判断当前正在调用的字符串是否匹配参数指定的正则表达式规则 |
方法名称 | 方法说明 |
---|---|
String[] split(String regex) | 参数regex为正则表达式,以regex所表示的字符串为分隔符,将字符串拆分成字符串数组 |
String replace(char oldChar, char newChar) | 使用参数newChar替换此字符串中出现的所有参数oldChar |
String replaceFirst(String regex, String replacement) | 替换此字符串匹配给定的正则表达式的第一个子字符串 |
String replaceAll(String regex, String replacement) | 将字符串中匹配正则表达式regex的字符串替换成replacement |
可变字符串类和日期相关类
可变字符串类
- 由于String类描述的字符串是个常量不可改变,当需要在Java代码中描述大量类似的字符串时,只能单独申请和存储,此时会造成内存空间的浪费。
- 为了解决上述问题,可以使用java.lang.StringBuilder类和java.lang.StringBuffer类来描述字符序列可以改变的字符串
- StringBuffer类是从JDK1.0开始存在,属于线程安全的类,因此效率较低
- StringBuilder类是从JDK1.5开始存在,属于非线程安全类,效率较高
StringBuilder类常用的构造方法
方法声明 | 功能介绍 |
---|---|
StringBuilder() | 使用无参方式构造对象,容量为16 |
StringBuilder(int capacity) | 使用参数指定的容量来构造对象,容量为参数指定大小 |
StringBuilder(String str) | 根据参数指定的字符串来构造对象,容量为:16+字符串长度 |
StringBuilder类常用的成员方法
方法声明 | 功能介绍 |
---|---|
int capacity() | 用于反幻觉调用对象的容量 |
int length() | 用于返回字符串的长度,也就是字符的个数 |
StringBuilder insert(int offset, String str) | 插入字符串并返回调用对象的引用 |
StringBuilder append(String str) | 追加字符串 |
StringBuilder deleteCharAt(int index) | 将当前字符串中下标为index位置的单个字符删除 |
StringBuilder delete(int start, int end) | 删除字符串 |
StringBuilder replace(int start, int end, String str) | 替换字符串 |
StringBuilder reverse() | 字符串反转 |
作为参数传递的话,方法内部的String不会改变其值,StringBuffer和StringBuilder会改变其值
返回值的设计
- StringBuilder的很多方法的返回值均为StringBuilder类型。这些方法的返回语句均为:return this
- 这些方法在对StringBuilder所封装的字符序列进行改变后又返回了该对象的引用。基于这样的设计目的在于可以连续调用
Java8之前的日期相关类
System类的概述
- java.lang.System类中提供的了一些有用的类字段和方法
常用的方法
方法声明 | 功能说明 |
---|---|
static long currentTimeMillis() | 返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间 |
Date类的概述
- java.util.Date类主要用于描述特定的瞬间,也就是年月日时分秒,可以精确到毫秒
常用的方法
方法声明 | 功能介绍 |
---|---|
Date() | 使用无参的方式构造对象,获取当前系统时间 |
Date(long date) | 根据参数指定毫秒数构造对象,参数为距离1970年1月1日0时0分0秒的毫秒数 |
long getTime() | 获取调用对象距离1970年1月1日0时0分0秒的毫秒数 |
void setTime(long time) | 设置调用对象为距离基准时间time毫秒的时间点 |
SimpleDateFormat类的概述
- java.text.SimpleDateFormat类主要用于实现日期和文本之间的转换
常用的方法
方法声明 | 功能介绍 |
---|---|
SimpleDateFormat() | 使用无参方式构造对象 |
SimpleDateFormat(String pattern) | 根据 参数指定的模式来构造对象,模式主要有:y-年M-月d-日H-时m-分s-秒 |
final String format(Date date) | 用于将日期类型转换为文本类型 |
Date parse(String source) | 用于将文本类型转换为日期类型 |
Calendar类的概述
- java.util.Calender类主要用于描述特定的瞬间,取代Date类中的过时方法实现全球化
- 该类是个抽象类,因此不能实例化对象,其具体子类针对不同国家的日历系统,其中应用最广泛的是GregorianCalendar(格里高利历),对应世界上绝大多数国家/地区使用的标准日历系统
常用的方法
方法声明 | 功能介绍 |
---|---|
static Calendar getInstance() | 用于获取Calendar类型的引用 |
void set(int year, int month, int date, int hourOfDay, int minute, int second) | 用于设置年月日时分秒信息 |
Date getTime() | 用于将Calendar类型转换为Date类型 |
void set(int field, int value) | 设置指定字段的数值 |
void add(int field, int amount) | 向指定字段增加数值 |
多态的使用场合
- 通过方法的参数传递形成多态
- 在方法体中直接使用多态的语法格式
- 通过方法的返回值类型形成多态
Java8中的日期相关类
Java8日期类的由来
JDK1.0中包含了一个java.util.Date类,但是它的大多数方法已经在JDK1.1引入Calendar类之后被弃用了。而Calendar类并不比Date类好多少。
- Date类的年份是从1900开始,而月份都是从0开始
- 格式化只对Date类有用,对Calendar类则不能使用
- 非线程安全
Java8日期类的概述
- Java8通过发布新的Date-Time API来进一步加强对日期与时间的处理
- java.time包:该包日期/时间API的基础包
- java.time.chrono包:该包提供对不同日历系统的访问
- java.time.format包:该包能够格式化和解析日期的时间对象
- java.time.temporal包:该包包含底层框架和扩展特性
- java.time.zone包:该包支持不同时区以及相关规则的类
LocalDate类的概述
- java.time.LocalDate类主要用于描述年-月-日格式的日期信息,该类不表示时间和时区信息
常用的方法
方法声明 | 功能介绍 |
---|---|
static LocalDate now() | 在默认时区中从系统时钟获取当前日期 |
LocalTime类的概述
- java.time.LocalTime类主要描述时间信息,可以描述时分秒以及纳秒
常用的方法
方法声明 | 功能介绍 |
---|---|
static LocalTime now() | 从默认时区的系统时间中获取当前时间 |
static LocalTime now(ZoneId zone) | 获取指定时区的当前时间 |
LocalDateTime类的概述
- java.time.LocalDateTime类主要用于描述ISO-8601日历系统中没有时区的日期时间
常用的方法
方法声明 | 功能介绍 |
---|---|
static LocalDateTime now() | 从默认时区的系统时间中获取当前日期时间 |
static LocalDateTime of(int year, int month, int dayOfMonth, intt hour, int minute, int second) | 根据参数指定的年月日时分秒信息来设置日期时间 |
int getYear() | 获取年份字段的数值 |
int getMonthValue() | 获取1到12之间的月份字段 |
int getDayOfMonth() | 获取日期字段 |
int getHour() | 获取小时数 |
int getMinute() | 获取分钟数 |
int getSecond() | 获取秒数 |
LocalDateTime withYear(int year) | 设置为参数指定的年 |
LocalDateTime withMonth(int month) | 设置为参数指定的月 |
LocalDateTime withDayOfMonth(int dayOfMonth) | 设置为参数指定的日 |
LocalDateTime withHour(int hour) | 设置为参数指定的时 |
LocalDateTime withMinute(int minute) | 设置为参数指定的分 |
LocalDateTime withSecond(int second) | 设置为参数指定的秒 |
LocalDateTime plusYear(long years) | 加上参数指定的年 |
LocalDateTime plusMonth(long months) | 加上参数指定的月 |
LocalDateTime plusDays(long days) | 加上参数指定的日 |
LocalDateTime plusHours(long hours) | 加上参数指定的时 |
LocalDateTime plusMinutes(long minutes) | 加上参数指定的分 |
LocalDateTime plusSeconds(long seconds) | 加上参数指定的秒 |
LocalDateTime minusYears(long years) | 减去参数指定的年 |
LocalDateTime minusMonths(long months) | 减去参数指定的月 |
LocalDateTime minusDays(long days) | 减去参数指定的日 |
LocalDateTime minusHours(long hours) | 减去参数指定的时 |
LocalDateTime minusMinutes(long minutes) | 减去参数指定的分 |
LocalDateTime minusSeconds(long seconds) | 减去参数指定的秒 |
Instant类的概述
- java.time.Instant类主要用于描述瞬间的时间点信息
常用的方法
方法声明 | 功能介绍 |
---|---|
static Instant now() | 从系统时钟上获取当前时间 |
OffsetDateTime atOffset(ZoneOffset offset) | 将此瞬间与偏移量组合以创建偏移日期时间 |
static Instant ofEpochMilli(long epochMilli) | 根据参数指定的毫秒数来构造对象,参数为距离1970年1月1日0时0分0秒的毫秒数 |
long toEpochMilli() | 获取距离1970年1月1日0时0分0秒的毫秒数 |
DateTimeFormatter类的概述
- java.time.format.DateTimeFormatter类主要用于格式化和解析日期
常用的方法
方法声明 | 功能介绍 |
---|---|
static DateTimeFormatter ofPattern(String pattern) | 根据参数指定的模式来获取对象 |
String format(TemporalAccessor temporal) | 将参数指定日期时间转换为字符串 |
TemporalAccessor parse(CharSequence text) | 将参数指定字符串转换为日期时间 |
集合类库
集合的概述
- 当需要在Java程序中记录单个数据内容时,则声明一个变量
- 当需要在Java程序中记录多个类型相同的数据时,声明一个一维数组
- 当需要在Java程序中记录多个类型不同的数据内容时,则创建一个对象
- 当需要在Java程序中记录多个类型相同的对象数据时,创建一个对象数组
- 当需要在Java程序中记录多个类型不同的对象数据时,则准备一个集合
集合的框架结构
- Java中集合框架顶层框架是:java.util.Collection集合和java.util.Map集合
- 其中Collection集合中存取元素的基本单位是:单个元素
- 其中Map集合中存取元素的基本单位是:单对元素
Collection集合
- java.util.Collection接口是List接口、Queue接口以及Set接口的父接口,因此该接口里定义的方法既可以用于操作List集合,也可以用于操作Queue集合和Set集合
常用的方法
方法声明 | 功能介绍 |
---|---|
boolean add(E e) | 向集合中添加对象 |
boolean addAll(Collection<? extends E> c) | 用于将参数指定集合c中的所有元素添加到当前集合中 |
boolean contains(Object o) | 判断是否包含对象 |
boolean containsAll(Collection<?> c) | 判断是否包含参数指定的所有对象 |
boolean retainAll(Collection<?> c) | 保留当前集合中存在且参数集合中存在的所有对象(取交集并保留) |
boolean remove(Objcet o) | 从集合中删除对象 |
boolean removeAll(Collection<?> c) | 从集合中删除参数指定的所有对象 |
void clear() | 清空集合 |
int size() | 返回包含对象的个数 |
boolean isEmpty() | 判断是否为空 |
boolean equals(Object o) | 判断是否相等 |
int hashCode() | 获取当前集合的哈希值 |
Object[] toArray() | 将集合转换为数组 |
Iterator iterator() | 获取当前集合的迭代器 |
Iterator接口
- java.util.Iterator接口主要用于描述迭代器对象,可以遍历Collection集合中的所有元素
- java.util.Collection接口继承Iterator接口,因此所有实现Collection接口的实现类都可以使用该迭代器对象
常用的方法
方法声明 | 功能介绍 |
---|---|
boolean hasNext() | 判断集合中是否有可以迭代/访问的元素 |
E next() | 用于取出一个元素并指向下一个元素 |
void remove() | 用于删除访问到的最后一个元素 |
在迭代一个集合的时候,禁止对该集合进行集合自身的删除操作,该操作会造成迭代结果的不确定,抛出ConcurrentModificationException
for each循环
- Java5推出了增强型for循环语句,可以应用数组和集合的遍历
- 是经典迭代的简化版
语法格式
for (元素类型 变量名: 数组/集合名称) {
循环体;
}
执行流程
- 不断地从数组/集合中取出一个元素赋值给变量名并执行循环体,直到取完所有元素为止
List集合
- java.util.List集合是Collection集合的子集合,该集合中允许有重复的元素并且有先后放入次序
- 该集合的主要实现类有:ArrayList类、LinkedList类、Stack类、Vector类
- 其中ArrayList类的底层是采用动态数组进行数据管理的,支持下标访问,增删元素不方便
- 其中LinkedList类的底层是采用双向链表进行数据管理的,访问不方便,增删元素方便
- 可以认为ArrayList和LinkedList的方法在逻辑上完全一样,只是在性能上有一定的差别,ArrayList更适合于随机访问,而LinkedList更适合于插入和删除;在性能不是特别苛刻的情形下可以忽略这个差别
- 其中Stack类的底层是采用动态数组进行数据管理的,该类主要用于描述一种具有后进先出特征的数据结构,叫做栈(Last in fast out LIFO)
- 其中Vector类的底层是采用动态数组进行数据管理的,该类与ArrayList类相比属于线程安全的,效率比较低,以后开发中基本不用
常用的方法
方法声明 | 功能介绍 |
---|---|
void add(int index, E element) | 向集合中指定位置添加元素 |
boolean addAll(int index, Collection<? extends E> c) | 向集合中添加所有元素 |
E get(int index) | 从集合中获取指定位置元素 |
int indexOf(Object o) | 查找参数指定的对象 |
int lastIndexOf(Object o) | 反向查找参数指定的对象 |
E set(int index, E element) | 修改指定位置的元素 |
E remove(int index) | 删除指定位置的元素 |
List subList(int fromIndex, int toIndex) | 用于获取子List |
Queue集合
- java.util.Queue集合是Collection集合的子集合,与List集合属于平级关系
- 该集合的主要用于描述具有先进先出特征的数据结构,叫做队列(First in first out FIFO)
- 该集合的主要实现类是LinkedList类,因为该类在增删方面比较有优势
常用的方法
方法声明 | 功能介绍 |
---|---|
boolean offer(E e) | 将一个对象添加至队尾,若添加成功则返回true |
E poll() | 从队首删除并返回一个元素 |
E peek() | 返回队首的元素(但并不删除) |
泛型机制
基本概念
- 通常情况下集合中可以存放不同类型的对象,是因为将所有对象都看作Object类型放入的,因此从集合中取出元素时也是Object类型,为了表达元素真实的数据类型,则需要强制类型转换,而强制类型转换可能会引发类型转换异常
- 为了避免上述错误的发生,从Java5开始增加泛型机制,也就是在集合名称的右侧使用<数据类型>的方式来明确要求该集合中可以存放的元素类型,若放入其他类型的元素则编译报错。
- 泛型只在编译时期有效,在运行时期不区分是什么类型
底层原理
- 泛型的本质就是参数化类型,也就是让数据类型作为参数传递,其中E相当于形式参数负责占位,而使用集合时<>中的数据类型相当于实际参数,用于给形式参数E进行初始化,从而使得集合中所有的E被实际参数替换,由于实际参数可以传递各种各样广泛的数据类型,因此得名为泛型。
自定义泛型接口
泛型接口和普通接口的区别就是后面添加了类型参数列表,可以有多个类型参数,如:<E, T, …>等
自定义泛型类
- 泛型类和普通类的区别就是类名后面添加了类型参数列表,可以多个类型参数,如<E, T, …>等
- 实例化泛型类时应该指定具体的数据类型,并且是引用数据类型而不是基本数据类型
- 父类有泛型,子类可以保留泛型也可以选择指定泛型
- 子类除了指定或保留父类的泛型,还可以增加自己的泛型
自定义泛型方法
-
泛型方法就是我们输入参数的时候,输入的是泛型参数,而不是具体的参数。我们在调用这个泛型方法的时候需要对泛型参数进行实例化
-
泛型方法的格式
[访问权限] <泛型> 返回值类型 方法名([泛型标识 参数名称]) { 方法体; }
-
在静态方法中使用泛型参数的时候,需要我们把静态方法定义为泛型方法
泛型在继承上的体现
- 如果B是A的一个子类或子接口,而G是具有泛型声明的类或接口,则G并不是G的子类型
通配符的使用
- 有时候我们希望传入的类型在一个指定的范围内,此时就可以使用泛型通配符了
- 泛型中有三种通配符形式:
- <?>无限制通配符:表示我们可以传入任意类型的参数(不支持元素的添加操作)
- <? extends E>表示类型的上界是E,只能是E或者是E的子类(不支持元素的添加操作)
- <? super E>表示类型的下界是E,只能是E或者是E的父类
Set集合
基本概念
- java.util.Set集合是Collection集合的子集合,与List集合平级
- 该集合中元素没有先后放入次序,且不允许重复
- 该集合的主要实现类是:HashSet类和TreeSet类以及LinkedHashSet类
- 其中HashSet类的底层是采用哈希表进行数据管理
- 其中TreeSet类的底层是采用红黑树进行数据管理的
- 其中LinkedHashSet类与HashSet类的不同之处在于维护了一个双向链表,链表中记录了元素的迭代顺序,也就是元素插入集合中的先后顺序,因此便于迭代
常用的方法
- 参考Collection集合中的方法即可
元素放入HashSet集合的原理
- 使用元素调用hashCode方法获取对应的哈希值,再由某种哈希算法计算出该元素在数组中的索引位置
- 若该位置没有元素,则将该元素直接放入即可
- 若该位置有元素,则使用新元素与已有元素依次比较哈希值,若哈希值不相同,则将该元素直接放入
- 若新元素与已有元素的哈希值相同,则使用新元素调用equals方法与已有元素依次比较
- 若相等则添加元素失败,否则将元素直接放入即可
为什么要求重写equals方法后要重写hashCode方法呢?
当两个元素调用equals方法相等时证明着两个元素相同,重写hashCode方法后保证这两个元素得到的哈希值相同,由同一个哈希算法生成的索引位置相同,此时只需要与该索引位置已有元素比较即可,从而提高效率并避免重复元素的出现。
TreeSet集合的概念
-
二叉树主要指每个节点最多只有两个子节点的树形结构
-
满足以下3个特征的二叉树叫做有序二叉树
- 左子树中的任意节点元素都小于根节点元素值
- 右子树中的任意节点元素都大鱼根节点元素值
- 左子树和右子树的内部也遵守上述规则
-
由于TreeSet集合的底层采用红黑树进行数据的管理,当有新元素插入到TreeSet集合时,需要使用新元素与集合中已有的元素依次比较来确定新元素的合理位置
-
比较元素大小的规则有两种方式
-
使用元素的自然排序规则进行比较并排序,让元素类型实现java.lang.Comparable接口
-
使用比较器规则进行比较并排序,构造TreeSet集合时传入java.util.Comparator接口
-
-
自然排序的规则比较单一,而比较器的规则比较多元化,而且比较器优先于自然排序
Map集合
基本概念
-
java.util.Map<K, V>集合中存取元素的基本单位是:单对元素,其中类型参数如下:
K:此映射所维护的键的类型,相当于目录
V:映射值的类型,相当于内容
-
该集合中key是不允许重复的,而且一个key只能对应一个value
-
该集合的主要实现类有:HashMap类、TreeMap类、LinkedHashMap类、Hashtable类、Properties类
-
其中HashMap类的底层是采用哈希表进行数据管理的
-
其中TreeMap类的底层是采用红黑树进行数据管理的
-
其中LinkedHashMap类与HashMap类的不同之处在于内部维护了一个双向链表,链表中记录了元素的迭代顺序,也就是元素插入集合中的先后顺序,因此便于迭代
-
其中Hashtable类是很古老的Map实现类,与HashMap相比属于线程安全的类,切不允许null作为key或value的值
-
其中Properties类是Hashtable的子类,该对象用于处理属性文件,key和value都是String类型的
-
Map集合是面向查询优化的数据结构,在大数据量情况下有着优良的查询性能
-
经常用于key检索value的业务场景
常用的方法
方法声明 | 功能介绍 |
---|---|
V put(K key, V value) | 将Key-Value对存入Map,若集合中已经包含该Key,则替换该Key所对应的Value,返回值为该Key原来所对应的Value,若没有则返回null |
V get(Object key) | 返回与参数Key所对应的Value对象,如果不存在则返回null |
boolean containsKey(Object key) | 判断集合中是否包含指定的Key |
boolean containsValue(Object value) | 判断集合中是否包含指定的Value |
V remove(Object key) | 根据参数指定的key进行删除 |
Set keySet() | 返回此映射中包含的键的Set视图 |
Collection values() | 返回此映射中包含的值的Set视图 |
Set<Map.Entry<K, V>> entrySet() | 返回此映射中包含的映射的Set视图 |
元素放入HashMap集合的原理
- 使用元素的key调用hashCode方法获取对应的哈希值,再由某种哈希算法计算在数组中的索引位置
- 若该位置没有元素,则将该键值对直接放入即可
- 若该位置有元素,则使用key与已有元素依次比较哈希值,若哈希值不相同,则将该元素直接放入
- 若key与已有元素的哈希值相同,则使用key调用equals方法与已有元素依次比较
- 若相等则将对应的value修改,否则将键值对直接放入即可
相关的常量
- DEFAULT_INITIAL_CAPACITY:HashMap的默认容量是16
- DEFAULT_LOAD_FACTOR:HashMap的默认加载因子是0.75
- threshold:扩容的临界值,该数值为 容量 *填充因子, 也就是12
- TREEIFY_THRESHOLD:若Bucket中链表长度大于该默认值则转化为红黑树存储,该数值是8
- MIN_TREEIFY_CAPACITY:桶中的Node被树化时最小的hash表容量,该数值是64
Collections类
基本概念
- java.util.Collections类主要提供了对集合操作或者返回集合的静态方法
常用的方法
方法声明 | 功能介绍 |
---|---|
static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) | 根据元素的自然顺序返回给定集合的最大元素 |
static T max(Collection<? extends T> coll, Comparator<? super T> comp) | 根据指定比较器引发的顺序返回给定集合的最大元素 |
static <T extends Object & Comparable <? super T>> T min(Collection<? extends T> coll) | 根据元素的自然顺序返回给定集合的最小元素 |
static T min(Collection<? extends T> coll, Comparator<? super T> comp) | 根据指定比较器引发的顺序返回给定集合的最小元素 |
static void copy(List<? super T> dest, List<? extends T> src) | 将一个列表中的所有元素复制到另一个列表中 |
static void reverse(List<?> list) | 反转指定列表中元素的顺序 |
static void shuffle(List<?> list) | 使用默认的随机源随机置换指定的列表 |
static <T extends Comparable<? super T>> void sort(LIst list) | 根据其元素的自然顺序将指定列表按升序排序 |
static void sort(List list, Comparator<? super T> c) | 根据指定比较器指定的顺序对指定列表进行排序 |
static void swap(List<?>, int i, int j) | 交换指定列表中指定位置的元素 |
异常机制和File类
异常机制
基本概念
- 异常就是“不正常”的含义,在Java语言中主要指程序执行中发生的不正常情况
- java.lang.Throwable类是Java语言中错误(Error)和异常(Exception)的超类
- 其中Error类主要用于描述Java虚拟机无法解决的严重错误,通常无法编码解决,如:JVM挂掉了等
- 其中Exception类主要用于描述因编程错误或偶然外在因素的轻微错误,通常可以编码解决,如:将0作为除数等
异常的分类
-
java.lang.Exception类是所有异常的超类,主要分为以下几种:
RuntimeException:运行时异常,也叫作非检测性异常
IOException和其他异常:也叫作检测性异常,所谓检测性异常就是指在编译阶段都能被编译器检测出来的异常
-
其中RuntimeException类的主要子类:
ArithmeticException类:算术异常
ArrayIndexOutOfBoundsException类:数组下标越界异常
NullPointerException类:空指针异常
ClassCastException类:类型转换异常
NumberFormatException类:数字格式异常
-
注意
当程序执行过程中发生异常但又没有手动处理时,则由Java虚拟机采用默认方式处理异常,而默认处理方式就是:打印异常的名称、异常发生的原因、异常发生的位置以及终止程序
异常的避免
- 在以后的开发中尽量使用if条件来判断来避免异常的发生
- 但是过多的if条件判断会导致程序的代码加长、臃肿,可读性差
异常的捕获
-
语法格式
try { 编写可能发生异常的代码; } catch (异常类型 引用变量名) { 编写针对该类异常的处理代码; } finally { 编写无论是否发生异常都要执行的代码; }
-
注意事项
-
当需要编写多个catch分支时,切记小类型应该放在大类型的前面
-
懒人的写法
catch (Exception e) { }
-
finally通常用于进行善后处理,如:关闭已经打开的文件等
-
-
执行流程
try { a; b; c; } catch (Exception e) { d; } finally { e; }
当没有发生异常时的执行流程:abce
当发生异常时的执行流程:abde
异常的抛出
-
基本概念
在某些特殊情况下有些异常不能处理或者不便于处理时,就可以将该异常转移给该方法的调用者,这种方法就叫异常的抛出。当方法执行时出现异常,则底层生成一个异常类对象抛出,此时异常代码后续的代码就不再执行
-
语法格式
访问权限 返回值类型 方法名称(形参列表) throws 异常类型1, 异常类型2... { 方法体; }
-
方法重写的原则
- 要求方法名相同、参数列表相同以及返回值类型相同,从jdk1.5开始支持返回子类类型
- 要求方法的访问权限不能变小,可以相同或者变大
- 要求方法不能抛出更大的异常
-
注意
子类重写的方法不能抛出更大的异常、不能抛出平级不一样的异常,但可以抛出一样的异常、更小的异常以及不抛出异常
-
经验分享
- 若父类中被重写的方法没有抛出异常时,则子类中重写的方法只能进行异常的捕获处理
- 若一个方法内部又以递进方式分别调用了好几个其他方法,则建议这些方法内可以使用抛出的方法处理到最后一层进行捕获方式处理
throws后接异常类型,放在函数形参列表后面。throw后接一个对象,放在方法体内
自定义异常
-
基本概念
当需要在程序中表达年龄不合理的情况时,而Java官方有没有提供这类针对性的异常,此时就需要自定义异常加以描述
-
实现流程
- 自定义xxxException异常类继承Exception类或者其子类
- 提供两个版本的构造方法,一个是无参构造方法,另外一个是字符串作为参数的构造方法
-
异常的产生
throw new 异常类型(实参);
-
Java采用的异常处理机制是将异常处理的程序代码集中在一起,与正常的程序代码分开,使得程序简洁、优雅,并易于维护
File类
基本概念
- java.io.File类主要用于描述文件或目录路径的抽象表示信息,可以获取文件或目录的特征信息,如:大小等
常用的方法
方法声明 | 功能概述 |
---|---|
File(String pathname) | 根据参数指定的路径名来构造对象 |
File(String parent, String child) | 根据参数指定的父路径和子路径信息构造对象 |
File(File parent, String child) | 根据参数指定的父抽象路径和子路径信息构造对象 |
boolean exists() | 测试此抽象路径名表示的文件或目录是否存在 |
String getName() | 用于获取文件的名称 |
long length() | 返回由此抽象路径名表示的文件的长度 |
long lastModified() | 用于获取文件的最后一次修改时间 |
String getAbsolutePath() | 用于获取绝对路径信息 |
boolean delete() | 用于删除文件,当删除目录时要求是空目录 |
boolean createNewFile() | 用于创建新的空文件 |
boolean mkdir() | 用于创建目录 |
boolean mkdirs() | 用于创建多级目录 |
File[] listFiles() | 获取该目录下的所有内容 |
boolean isFile() | 判断是否为文件 |
boolean isDirectory() | 判断是否为目录 |
File[] listFiles(FileFilter filter) | 获取目录下满足筛选器的所有内容 |
IO流
IO流的概念
- IO就是Input和Output的简写,即输入和输出
- IO流就是指读写数据时像流水一样从一端流到另外一端,因此得名为“流”
基本分类
-
按照读写数据的基本单位不同,分为字节流和字符流
其中字节流主要指以字节为单位进行数据读写的流,可以读写任意类型的文件
其中字符流主要指以字符(2个字节)为单位进行数据读写的流,只能读写文本文件
-
按照读写数据的方向不同,分为输入流和输出流
其中输入流主要指从文件中读取数据内容输入到程序中,也就是读文件
其中输出流主要指将程序中的数据内容输出到文件中,也就是写文件
-
按照流的角色不同分为节点流和处理流
其中节点流主要指直接和输入输出源对接的流
其中处理主要指需要建立在节点流的基础之上的流
体系结构
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
访问字符串 | __ | __ | StringReader | StringWriter |
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | __ | __ | InputStreamReader | OutputStreamWriter |
对象流 | ObjectInputStream | ObjectOutputStream | __ | __ |
FilterInputStream | FilterOutputStream | FilterReader | FilterWriter | |
打印流 | __ | PrintStream | __ | PrintWriter |
推回输入流 | PushbackInputStream | __ | PushbackReader | __ |
特殊流 | DataInputStream | DataOutputStream | __ | __ |
相关流的详解
FileWriter类
基本概念
- java.io.FileWriter类主要用于将文本内容写入到文本文件
常用的方法
方法声明 | 功能介绍 |
---|---|
FileWriter(String fileName) | 根据参数指定的文件名构造对象 |
FileWriter(String fileName, boolean append) | 以追加的方式根据参数指定的文件名来构造对象 |
void write(int c) | 写入单个字符 |
void write(char[] cbuf, int off, int len) | 将指定字符数组中从偏移量off开始的len个字符写入此文件输出流 |
void write(char[] cbuf) | 将cbuf.length个字符从指定字符数组写入此文件输出流中 |
void flush() | 刷新流 |
void close() | 关闭流对象并释放有关的资源 |
FileReader类
基本概念
- java.io.FileReader类主要用于从文本文件读取文本数据内容
常用的方法
方法声明 | 功能介绍 |
---|---|
FileReader(String fileName) | 根据参数指定的文件名构造对象 |
int read() | 读取单个字符的数据并返回,返回-1表示读取到末尾 |
int read(char[] cbuf, int offset, int length) | 从输入流中将最多len个字符的数据读入一个字符数组中,返回读取到的字符个数,返回-1表示读取到末尾 |
int read(char[] cbuf) | 从此输入流中将最多cbuf.length个字符的数据读入字符数组中,返回读取到的字符个数,返回-1表示读取到末尾 |
void close() | 关闭流对象并释放有关的资源 |
FileOutputStream类
基本概念
- java.io.FileOutputStream类主要用于将图像数据之类的原始字节流写入到输出流中
常用的方法
方法声明 | 功能介绍 |
---|---|
FileOutputStream(String name) | 根据参数指定的文件名来构造对象 |
FileOutputStream(String name, boolean append) | 以追加的方式根据参数指定的文件名来构造对象 |
void write(int b) | 将指定字节写入此文件输出流 |
void write(byte[] b, int off, int len) | 将指定字节数组中从偏移量off开始的len个字节写入此文件输出流 |
void write(byte[] b) | 将b.length个字节从指定字节数组写入此文件的输出流中 |
void flush() | 刷新此输出流并强制写出任何缓冲的输出字节 |
void close() | 关闭流对象并释放有关的资源 |
FileInputStream类
基本概念
- java.io.FileInputStream类主要用于从输入流中以字节流的方式读取图像数据等
常用的方法
方法声明 | 功能介绍 |
---|---|
FileInputStream(String name) | 根据参数指定的文件路径名来构造对象 |
int read() | 从输入流中读取单个字节的数据并返回,返回-1表示读取到末尾 |
int read(byte[] b, int off, int len) | 从此输入流中将最多len个字节的数据读入字节数组中,返回读取到的字节个数,返回-1表示读取到末尾 |
int read(byte[] b) | 从此输入流中将最多b.length个字节的数据读入字节数组中,返回读取到的字节个数,返回-1表示读取到末尾 |
void close() | 关闭流对象并释放有关的资源 |
int available() | 获取输入流所关联文件的大小 |
BufferedOutputStream类
基本概念
- java.io.BufferedOutputStream类主要用于描述缓冲输出流,此时不用为写入的每个字节调用底层系统
常用的方法
方法声明 | 功能介绍 |
---|---|
BufferedOutputStream(OutputStream out) | 根据参数指定的引用来构造对象 |
BufferedOutputStream(OutputStream out, int size) | 根据参数指定的引用和缓冲区大小来构造对象 |
void write(int b) | 写入单个字节 |
void write(byte[] b, int off, int len) | 写入字节数组中的一部分数据 |
void write(byte[] b) | 写入参数指定的整个字节数组 |
void flush() | 刷新流 |
void close() | 关闭流对象并释放有关的资源 |
BufferedInputStream类
基本概念
- java.io.BufferedInputStream类主要用于描述缓冲输入流
常用的方法
方法声明 | 功能介绍 |
---|---|
BufferedInputStream(InputStream in) | 根据参数指定的引用构造对象 |
BufferedInputStream(InputStream in, int size) | 根据参数指定的引用和缓冲区大小构造对象 |
int read() | 读取单个字节 |
int read(byte[] b, int off, int len) | 读取len个字节 |
int read(byte[] b) | 读取b.length个字节 |
void close() | 关闭流对象并释放有关的资源 |
BufferedWriter类
基本概念
- java.io.BufferedWriter类主要用于写入单个字符、字符数组以及字符串到输出流中
常用的方法
方法声明 | 功能介绍 |
---|---|
BufferedWriter(Writer out) | 根据参数指定的引用来构造对象 |
BufferedWriter(Writer out, int sz) | 根据参数指定的引用和缓冲区大小来构造对象 |
void write(int c) | 写入单个字符到输出流中 |
void write(char[] cbuf, int off, int len) | 将字符数组cbuf中从下标off开始的len个字符写入输出流中 |
void write(char[] cbuf, int off, int len) | 将字符数组cbuf中从下标off开始的len个字符写入输出流中 |
void write(char[] cbuf) | 将字符串数组cbuf中所有内容写入输出流中 |
void write(String s, int off, int len) | 将参数s中下标从off开始的len个字符写入输出流中 |
void write(String str) | 将参数指定的字符串内容写入输出流中 |
void newLine() | 用于写入行分隔符到输出流中 |
void flush() | 刷新流 |
void close() | 关闭流对象并释放有关的资源 |
BufferedReader类
基本概念
- java.io.BufferedReader类用于从输入流中读取单个字符、字符数组以及字符串
常用的方法
方法声明 | 功能介绍 |
---|---|
BufferedReader(Reader in) | 根据参数指定的引用来构造对象 |
BufferedReader(Reader in, int sz) | 根据参数指定的引用和缓冲区大小来构造对象 |
int read() | 从输入流读取单个字符,读取到末尾则返回-1,否则返回实际读取到的字符内容 |
int read(char[] cbuf, int off, int len) | 从输入流中读取len个字符放入数组cbuf中下标从off开始的位置上,若读取到末尾则返回-1,否则返回实际读取到的字符个数 |
int read(char[] cbuf) | 从输入流中读满整个数组cbuf |
String readLine() | 读取一行字符串并返回,返回null表示读取到末尾 |
void close() | 关闭流对象并释放有关的资源 |
PrintStream类
基本概念
- java.io.PrintStream类主要用于更加方便的打印各种数据内容
常用的方法
方法声明 | 功能介绍 |
---|---|
PrintStream(OutputStream out) | 根据参数指定的引用来构造对象 |
void print(String s) | 用于将参数指定的字符串内容打印出来 |
void println(String x) | 用于打印字符串后并终止该行 |
void flush() | 刷新流 |
void close() | 用于关闭输出流并释放有关的资源 |
PrintWriter类
基本概念
- java.io.PrintWriter类主要用于将对象的格式化形式打印到文本输出流
常用的方法
方法声明 | 功能介绍 |
---|---|
PrintWriter(Writer out) | 根据参数指定的引用来构造对象 |
void print(String s) | 将参数指定的字符串内容打印出来 |
void println(String x) | 打印字符串后并终止该行 |
void flush() | 刷新流 |
void close() | 关闭流对象并释放有关的资源 |
OutputStreamWriter类
基本概念
- java.io.OutputStreamWriter类主要用于实现从字符流到字节流的转换
常用的方法
方法声明 | 功能介绍 |
---|---|
OutputStreamWriter(OutputStream out) | 根据参数指定的引用来构造对象 |
OutputStreamWriter(OutputStream out, String charsetName) | 根据参数指定的引用和编码构造对象 |
void write(String str) | 将参数指定的字符串写入 |
void flush() | 刷新流 |
void close() | 用于关闭输出流并释放有关的资源 |
InputStreamReader类
基本概念
- java.io.InputStreamReader类主要用于实现从字节流到字符流的转换
常用的方法
方法声明 | 功能介绍 |
---|---|
InputStreamReader(InputStream in) | 根据参数指定的引用来构造对象 |
InputStreamReader(InputStream in, String charsetName) | 根据参数指定的引用和编码来构造对象 |
int read(char[] cbuf) | 读取字符数据到参数指定的数组 |
void close() | 用于关闭输出流并释放有关的资源 |
字符编码
编码表的由来
- 计算机只能识别二进制数据,早期就是电信号。为了方便计算机可以识别各个国家的文字,就需要将各个国家的文字采用数字编号的方式进行描述并建立对应的关系表,该表就叫做编码表
常见的编码表
- ASCII:美国标准信息交换码,使用一个字节的低7位二进制位表示
- ISO8859-1:拉丁码表,欧洲码表,使用一个字节的8位二进制位表示
- GB2312:中国的中文编码表,最多使用两个字节16位二进制位表示
- GBK:中国的中文编码表升级,融合了更多的中文文字符号,最多使用两个字节16位二进制位表示
- Unicode:国际标准码,融合了目前人类使用的所有字符,为每个字符分配唯一的字符码。所有的文字都用两个字节16位二进制位表示
编码的发展
- 面向传输的众多UTF(UCS Transfer Format)标准出现了,UTF-8就是每次8个位传输数据,而UTF-16就是每次16个位。这是为传输而设计的编码并使编码无国界,这样就可以显示全世界上所有文化的字符了
- Unicode只是定义了一个庞大的全球通用的字符集,并为每个字符规定了唯一确定的编号,具体存储成什么样的字节流,取决于字符编码方案。推荐的Unicode编码是UTF-8和UTF-16
- UTF-8:变长的编码方式,可用1-4个字节来表示一个字符
DataOutputStream类
基本概念
- java.io.OutputStream类主要用于以适当的方式将基本数据类型写入输出流中
常用的方法
方法声明 | 功能介绍 |
---|---|
DataOutputStream(OutputStream out) | 根据参数指定的引用构造对象(OutputStream类是个抽象类,实参需要传递子类对象) |
void writeInt(int v) | 用于将参数指定的整数一次性写入输出流,优先写入高字节 |
void close() | 用于关闭文件输出流并释放有关的资源 |
DataInputStream类
基本概念
- java.io.DataInputStream类主要用于从输入流中读取基本数据类型的数据
常用的方法
方法声明 | 功能介绍 |
---|---|
DataInputStream(InputStream in) | 根据参数指定的引用来构造对象(InputStream类是抽象类,实参需要传递子类对象) |
int readInt() | 用于从输入流中一次性读取一个整数数据并返回 |
void close() | 用于关闭输入流并释放有关的资源 |
ObjectOutputStream类
基本概念
- java.io.ObjectOutputStream类主要用于将一个对象的所有内容整体写入到输出流中
- 只能支持java.io.Serializable接口的对象写入流中
- 类通过实现java.io.Serializable接口以启用其序列化功能
- 所谓序列化主要指将一个对象需要存储的相关信息有效组织成字节序列的转化过程
常用的方法
方法声明 | 功能介绍 |
---|---|
ObjectOutputStream(OutputStream out) | 根据参数指定的引用来构造对象 |
void writeObject(Object obj) | 用于将参数指定的对象整体写入到输出流中 |
void close() | 用于关闭输出流并释放有关的资源 |
ObjectInputStream类
基本概念
- java.io.ObjectInputStream类主要用于从输入流中一次性将对象整体读取出来
- 所谓反序列化主要指将有效组织的字节序列恢复为一个对象及相关信息的转化过程
常用的方法
方法声明 | 功能介绍 |
---|---|
ObjectInputStream(InputStream in) | 根据参数指定的引用来构造对象 |
Object readObject() | 主要用于从输入流中读取一个对象并返回,无法通过返回值来判断是否读取到文件的末尾 |
void close() | 用于关闭输入流并释放有关的资源 |
序列化版本号
- 序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致行的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常(InvalidCastException)
transient关键字
- transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量时被包括进去的
经验的分享
- 当希望将多个对象写入文件时,通常建议将多个对象放入一个集合中,然后将集合这个整体看作一个对象写入输入流中,此时只需要调用一次readObject方法就可以将整个集合的数据读取出来,从而避免了通过返回值进行是否达到文件末尾的判断
RandomAccessFile类
基本概念
- java.io.RandomAccessFile类主要支持对随机访问文件的读写操作
常用的方法
方法声明 | 功能介绍 |
---|---|
RandomAccessFile(String name, String mode) | 根据参数指定的名称和模式构造对象(r:以只读方式打开 rw:打开一遍读取和写入 rwd:打开以便读取和写入,同步文件内容的更新 rws:打开以便读取和写入,同步文件内容和元数据的更新) |
int read() | 读取单个字节的数据 |
void seek(long pos) | 用预设值从此文件的开头开始测量的文件指针偏移量 |
void write(int b) | 将参数指定的单个字节写入 |
void close() | 用于关闭流并释放有关的资源 |
多线程
基本概念
程序和进程的概念
- 程序 = 数据结构 + 算法,主要指存放在硬盘上的可执行文件
- 进程 - 主要指运行在内存中的可执行文件
- 目前主流的操作系统支持多进程,为了让操作系统同时可以执行多个任务,但进程是重量级的,也就是新建一个进程会消耗CPU和内存空间等系统资源,因此进程的数量比较局限
线程的概念
- 为了解决上述问题就提出线程的概念,线程就是进程内部的程序流,也就是说操作系统内部支持多进程的,而每个进程的内部又是支持多线程的,线程是轻量的,新建线程会共享所在进程的系统资源,因此目前主流的开发都是采用多线程
- 多线程是采用时间片轮转法来保证多个线程的并发执行,所谓并发就是指宏观并行微观串行的机制
线程的创建
Thread类的概念
- java.lang.Thread类代表线程,任何线程对象都是Thread类(子类)的实例
- Thread类是线程的模板,封装了复杂的线程开启等操作,封装了操作系统的差异性
创建方式
- 自定义类继承Thread类并重写run方法,然后创建该类的对象调用start方法
- 自定义类实现Runnable接口并重写run方法,创建该类的对象作为实参来构造Thread类型的对象,然后使用Thread类型的对象调用start方法
相关的方法
方法声明 | 功能介绍 |
---|---|
Thread() | 使用无参的方式构造对象 |
Thread(String name) | 根据参数指定的名称来构造对象 |
Thread(Runnable target) | 根据参数指定的引用来构造对象,其中Runnale是个接口类型 |
Thread(Runnable target, String name) | 根据参数指定的引用和名称来构造对象 |
void run() | 若使用Runnable引用构造了线程对象,调用该方法时最终调用接口中的版本;若没有使用Runnable引用构造线程对象,调用该方法时则啥也不做 |
void start() | 用于启动线程,Java虚拟机会自动调用该线程的run方法 |
执行流程
- 执行main方法的线程叫做主线程,执行run方法的线程叫做新线程/子线程
- main方法是程序的入口,对于start方法之前的代码来说,由主线程执行一次,当start方法调用成功后线程的个数由一个变成了两个,新启动的线程去执行run方法的代码,主线程继续向下执行,两个线程各自独立运行互不影响
- 当run方法执行完毕后子线程结束,当main方法执行完毕后主线程结束
- 两个线程执行没有明确的先后执行次序,由操作系统调度算法来决定
方式的比较
- 继承Thread类的方式代码简单,但是若该类继承Thread类后则无法继承其他类,而实现Runnable接口的方式代码复杂,但不影响该类继承其他类以及实现其它接口,因此以后的开发中推荐使用第二种方式
匿名内部类的方式
- 使用匿名内部类的方式来创建和启动线程
线程的生命周期
- 新建状态:使用new关键字创建之后进入的状态,此时线程并没有开始执行
- 就绪状态:调用start方法后进入的状态,此时线程还是没有开始执行
- 运行状态:使用线程调度器调度该线程后进入的状态,此时线程开始执行,当线程的时间片执行完毕后任务没有完成时回到就绪状态
- 消亡状态:当线程的任务执行完成后进入的状态,此时线程已经停止
- 阻塞状态:当线程执行的过程中发生了阻塞事件进入的状态,阻塞状态解除后进入就绪状态
线程的编号和名称
方法声明 | 功能介绍 |
---|---|
long getId() | 获取调用对象所表示线程的编号 |
String getName() | 获取调用对象所表示线程的名称 |
void setName(String name) | 设置/修改线程的名称为参数指定的数值 |
static Thread currentThread() | 获取当前正在执行线程的引用 |
常用的方法
方法声明 | 功能介绍 |
---|---|
static void yield() | 当前线程让出处理器(离开Running状态),使当前线程进入Runnable状态等待 |
static void sleep(long times) | 使当前线程从Running放弃处理器进入Block状态,休眠times毫秒,再返回到Runnable。如果其他线程打断当前线程的Block(sleep),就会发生InterruptedException |
int getPriority() | 获取线程的优先级 |
void setPriority(int newPriority) | 修改线程的优先级。优先级越高的线程不一定先执行,但该线程获取到时间片的机会会更多一些 |
void join() | 等待该线程终止 |
void join(long millis) | 等待参数指定的毫秒数 |
boolean isDaemon() | 用于判断是否为守护线程 |
void setDaemon(boolean on) | 用于设置线程为守护线程 |
线程同步机制
基本概念
- 当多个线程同时访问同一种共享资源时,可能会造成数据的覆盖等不一致性问题,此时就需要对线程之间进行通信和协调,该机制就叫做线程的同步机制
- 多个线程并发读写同一个临界资源时会发生线程并发安全问题
- 异步操作:多线程并发的操作,各自独立运行
- 同步操作:多线程串行的操作,先后执行的顺序
解决方案
- 由程序结果可知:当两个线程同时对同一个账户进行取款时,导致最终的账户余额不合理
- 引发原因:线程一执行取款时还没有来得及将取款后的余额写入后台,线程二就已经开始取款
- 解决方案:让线程一执行完毕取款操作后,再让线程二执行即可,将线程的并发操作改为串行操作
- 经验分享:在以后的开发尽量减少串行操作的范围,从而提高效率
实现方式
-
在Java语言中使用synchronized关键字来实现同步/对象锁机制从而确保线程执行的原子性
-
// 使用同步代码块的方式实现部分代码的锁定 synchronized(类类型的引用) { 编写所有需要锁定的代码; }
-
// 使用同步方法的方式实现所有代码的锁定 // 直接使用synchronized关键字来修饰整个方法即可
静态方法的锁定
- 当我们对一个静态方法加锁,那么该方法锁的对象是类对象。每个类都有唯一的一个类对象。获取类对象的方式:类名.class
- 静态方法与非静态方法同时使用了synchronized后他们之间是非互斥关系的。静态方法锁的是类对象,而非静态方法锁的是当前方法的所属对象
注意事项
- 使用synchronized保证线程同步时应当注意
- 多个需要同步的线程在访问同步块时,看到的应该是同一个锁对象引用
- 在使用同步块时应当尽量减少同步范围以提高并发的执行效率
线程安全类和不安全类
- StringBuffer类是线程安全的类,但StringBuilder类不是线程安全的类
- Vector类和Hashtable类是线程安全的类,但ArrayList类和HashMap类不是线程安全的类
- Collections.synchronizedList()和Collections.synchronizedMap()等方法线程安全
死锁的概念
使用Lock(锁)实现线程同步
基本概念
- 从Java5开始提供了更强大的线程同步机制:使用显式定义的同步锁对象来实现
- java.util.concurrent.locks.Lock接口是控制多个线程对共享资源进行访问的工具
- 该接口的主要实现类是ReentrantLock类,该类拥有与synchronized相同的并发性,在以后的线程安全控制中,经常使用ReentrantLock类显式加锁和释放锁
常用的方法
方法声明 | 功能介绍 |
---|---|
ReentrantLock() | 使用无参方式构造对象 |
void lock() | 获取锁 |
void unlock() | 释放锁 |
与synchronized方式的比较
- Lock是显式锁,需要手动实现开启和关闭操作,而synchronized是隐式锁,执行锁定代码后自动释放
- Lock只有同步代码块方式的锁,而synchronized有同步代码块方式和同步方法两种锁
- 使用Lock锁方式时,Java虚拟机将花费较少的时间来调度线程,因此性能更好
Object类常用的方法
方法声明 | 功能介绍 |
---|---|
void wait() | 用于使得线程进入等待状态,直到其他线程调用notify()或notifyAll()方法 |
void wait(long timeout) | 用于进入等待状态,直到其他线程调用方法或参数指定的毫秒数已经过去为止 |
void notify() | 用于唤醒等待的单个线程 |
void notifyAll() | 用于唤醒等待的所有线程 |
线程池
实现Callable接口
-
从Java5开始新增加创建线程的第三种方式为实现java.util.concurrent.Callable接口
-
常用的方法
方法声明 功能介绍 V call() 计算结果并返回
FutureTask类
-
java.util.concurrent.FutureTask类用于描述可取消的异步计算,该类提供了Future接口的基本实现,包括启动和取消计算、查询计算是否完成以及检索计算结果的方法,也可以用于获取方法调用后的返回结果
-
常用的方法
方法声明 功能介绍 FutureTask(Callable callable) 根据参数指定的引用来创建一个未来任务 V get() 获取call方法计算的结果
线程池的由来
- 在服务器编程模型的原理,每一个客户端连接用一个单独的线程为之服务,当与客户端的会话结束时,线程也就结束了,即没来一个客户端连接,服务器端就要创建一个新线程
- 如果访问服务器的客户端很多,那么服务器要不断地创建和销毁线程,这将严重影响服务器的性能
概念和原理
- 线程池的概念首先创建一些线程,它们的集合称为线程池,当服务器接受到一个客户请求后,就从线程池中取出一个空闲的线程为之服务,服务完后不关闭该线程,而是将该线程还回到线程池中
- 在线程池的编程模式下,任务是提交给整个线程池,而不是直接交给某个线程,线程池拿到任务后,它就在内部找有无空闲的线程,再把任务交给内部某个空闲的线程,任务是提交给整个线程池,一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务
相关类和方法
-
从Java5开始提供了线程池的相关类和接口:java.util.concurrent.Executors类和java.util.concurrent.ExcutorService接口
-
其中Executors是个工具类和线程池的工厂类,可以创建并返回不同类型的线程池,常用方法如下
方法声明 功能介绍 static ExecutorService newCachedThreadPool() 创建一个可根据需要创建新线程的线程池 static ExecutorService newFixedThreadPool(int nThreads) 创建一个可重用固定线程数的线程池 static ExecutorService newSingleThreadExecutor() 创建一个只有一个线程的线程池 -
其中ExecutorService接口是真正的线程池接口,主要实现类是ThreadPoolExecutor,常用方法如下
方法声明 功能介绍 void execute(Runnable command) 执行任务和命令,通常用语执行Runnable Future submit(Callable task) 执行任务和命令,通常用于执行Callable void shutdown() 启动有序关闭
网络编程
网络编程的常识
- 目前主流的网络通讯软件有:微信、QQ、飞信、阿里旺旺等
七层网络模型
-
OSI(Open System Interconnect),即开放式系统互联,是ISO(国际标准化组织)在1985年研究的网络互连模型
-
OSI七层模型和TCP/IP五层模型的划分
OSI:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
TCP/IP:应用层、传输层、网络层、数据链路层、物理层
OSI的应用层、表示层、会话层相当于TCP/IP的应用层,其协议类型有:HTTP、Telnet、FTP、TFTP、DNS、SMTP…
OSI的传输层相当于TCP/IP的传输层,其协议类型有:TCP、UDP…
网络层协议类型有:IP、ICMP、RIP、IGMP…
-
当发送数据时,需要对发送的内容按照上述模型进行层层加包后发送出去
-
当接收数据时,需要对接收的内容按照上述模型进行层层拆包并显示出来
相关的协议
协议的概念
- 计算机在网络中实现通信就必须有一些约定或者规则,这种约定和规则就叫做通信协议,通信协议可以对速率、传输代码、代码结构、传输控制步骤、出错控制等制定统一的标准
TCP协议
- 传输控制协议(Transmission Control Protocol),是一种面向连接的协议,类似于打电话
建立连接、进行通信、断开连接
在传输前采用“三次握手”方式
在通信的整个过程中全程保持连接,形成数据传输通道
保证了数据传输的可靠性和有序性
是一种全双工的字节流通信方式,可以进行大数据量的传输
传输完毕后需要释放已建立的连接,发送数据的效率比较低
UDP协议
- 用户数据报协议(User Datagram Protocol),是一种非面向连接的协议,类似于写信
在通信的整个过程中不需要保持连接,其实不需要建立连接
不保证数据传输的可靠性和有序性
是一种全双工的数据报通信方式,每个数据报的大小限制在64K内
发送数据完毕后无需释放资源,开销小,发送数据的效率比较高,速度快
IP地址
-
IP地址是互联网中的唯一地址标识,本质上是由32位二进制数组成的整数,叫做IPv4。同时也有128位二进制位组成的整数,叫做IPv6
-
日常生活中采用点分十进制表示法来进行IP地址的描述,将每个字节的二进制转化为一个十进制整数,不同的整数之间采用小数点隔开
-
特殊的地址
本地回环地址(hostAddress):127.0.0.1 主机名(hostName):localhost
端口号
-
IP地址:可以定位到具体某一设备
-
端口号:可以定位到该设备中具体某一个进程
-
端口号本质上是16位二进制组成的整数,表示范围是0~65535,其中0~1024之间的端口号通常被系统占用,建议从1025开始使用
-
特殊的端口号
HTTP:80 FTP:21
-
网络编程需要提供IP地址+端口号,组合在一起叫做网络套接字(Socket)
基于TCP协议的编程模型
C/S架构的简介
- 在C/S模式下客户向服务器发出服务请求,服务器接收到请求后提供服务
- 客户端部分:为每个用户所专有,负责执行前台功能
- 服务器部分:由多个用户共享的信息与功能,招待后台服务
编程模型
- 服务器
- 创建ServerSocket类型的对象并提供端口号
- 等待客户端的连接请求,调用accept方法
- 使用输入输出流进行通信
- 关闭Socket并释放相关的资源
- 客户端
- 创建Socket类型的对象并提供服务器的IP地址和端口号
- 使用输入输出流通信
- 关闭Socket并释放相关的资源
相关类和方法的解析
ServerSocket类
-
java.net.ServerSocket类主要用于描述服务器套接字信息
-
常用的方法如下
方法声明 功能介绍 ServerSocket(int port) 根据参数指定的端口号来构造对象 Socket accept() 侦听并接收到此套接字的连接请求 void close() 用于关闭套接字
Socket类
-
java.net.Socket类主要用于描述客户端套接字,是两台机器间通信的端点
-
常用的方法如下
方法声明 功能介绍 Socket(String host, int port) 根据指定的主机名和端口号来构造对象 InputStream getInputStream() 用于获取当前套接字的输入流 OutputStream getOutputStream() 用于获取当前套接字的输出流 void close() 用于关闭套接字
注意事项
- 客户端Socket与服务器端的Socket对应,都包含输入流和输出流
- 客户端的socket.getInputStream方法连接于服务器socket.getOutputStream方法
- 客户端的socket.getOutputStream方法连接于服务器socket.getInputStream方法
基于UDP协议的编程模型
编程模型
- 接收方
- 创建DatagramSocket类型的对象并提供端口号
- 创建DatagramPacket类型的对象并提供缓冲区
- 通过Socket接收数据内容存放到Packet中,调用receive方法
- 关闭Socket
- 发送方
- 创建DatagramSocket类型的对象
- 创建DatagramPacket类型的对象并提供接收方的通信地址
- 通过Socket将Packet中的数据内容发送出去,调用send方法
- 关闭Socket
相关类和方法的解析
DatagramSocket类
-
java.net.DatagramSocket类主要用于描述发送和接收数据报的套接字
-
常用的方法如下
方法声明 功能介绍 DatagramSocket() 使用无参的方式来构造对象 DatagramSocket(int port) 根据参数指定的端口号来构造对象 void receive(DatagramPacket p) 用于接收数据报存放到参数指定的位置 void send(DatagramPacket p) 用于将参数指定的数据报发送出去 void close() 关闭Socket并释放相关资源
DatagramPacket类
-
java.net.DatagramPacket类主要用于描述数据报,数据报用来实现无连接数据投递服务
-
常用的方法如下
方法声明 功能介绍 DatagramPacket(byte[] buf, int length) 根据参数指定的数组来构造对象,用于接收长度为length的数据报 DatagramPacket(byte[] buf, int length, InetAddress address, int port) 根据参数指定数组来构造对象,将数据报发送到指定地址和端口 InetAddress getAddress() 用于获取发送方或接收方的通信地址 int getPort() 用于获取发送方或接收方的端口号 int getLength() 用于获取发送数据或接收数据的长度
InetAddress类
-
java.net.InetAddress类主要用于描述互联网通信地址信息
-
常用的方法如下
方法声明 功能介绍 static InetAddress getLocalHost() 用于获取当前主机的通信地址 static InetAddress getByName(String host) 根据参数指定的主机名获取通信地址
URL类
基本概念
-
java.net.URL(Uniform Resource Identifier)类主要用于表示统一的资源定位器,也就是指向万维网上“资源”的指针。这个资源可以是简单的文件或目录,也可以是对复杂对象的引用
-
通过URL可以访问万维网上的网络资源,最常见的就是www和ftp站点,浏览器通过解析给定的URL可以在网络上查找相应的资源
-
URL的基本结构如下
<传输协议>://<主机名>: <端口号>/<资源地址>
常用的方法
方法声明 | 功能介绍 |
---|---|
URL(String spec) | 根据参数指定的字符串信息构造对象 |
String getProtocol() | 获取协议名称 |
String getHost() | 获取主机名称 |
int getPort() | 获取端口号 |
String getPath() | 获取路径信息 |
String getFile() | 获取文件名 |
URLConnection openConnection() | 获取URLConnection类的实例 |
URLConnection类
基本概念
- java.net.URLConnection类是个抽象类,该类表示应用程序和URL之间的通信链接的所有类的超类,主要实现类有支持HTTP特有功能的HttpURLConnection类
HttpURLConnection类的常用方法
方法声明 | 功能介绍 |
---|---|
InputStream getInputStream() | 获取输入流 |
void disconnect() | 断开连接 |
反射机制
基本概念
- 通常情况下编写代码都是固定的,无论运行多少次执行的结果也是固定的,在某些特殊场合中编写代码时不确定要创建什么类型的对象,也不确定要调用什么样的方法,这些都希望通过运行时传递的参数来决定,该机制叫做动态编程技术,也就是反射机制
- 目前主流的框架底层都是采用反射机制实现的
反射就是通过拿到对象类型的结构,再去用这个结构操作对象。例如通过对象的class对象,拿到所有的方法和字段列表,然后就可以调用方法,读写字段。
为什么会有反射?
面向对象其实是让我们在显式类型下去调用方法和读写字段,这就是所谓的良好的封装。知道一个类型,知道它所拥有的方法,代码里就可以用该类的一个实例去调用它的方法。有些时候,我们在编码阶段并不知道实例运行时具体的类型(实例可以有几种不同类型的实现,这些之间没关系),但是我们约定好了这个类型必须有一个方法,那么我们就需要破坏掉这种封装,直接通过实例运行期找到这个方法去操作。这样我们实际上实现了一个类似于字段/函数指针的功能。如果显式的面向对象操作就像是传统医学的望闻问切,那么反射就相当于拍CT,直接透视和操作对象内部了。
反射能做什么?
- 拿到对象的类型的内部结构
- 同样的代码操作不同类型对象
- 把编译期的一些类型检查挪到运行期
- 破坏对象私有限制,操作私有属性
- 现在用的很广的泛型和注解的很多东西,需要通过反射拿到对应标记
Class类
基本概念
- 通常情况下编写代码都是固定的,无论运行多少次执行的结果也是固定的,在某些特殊场合中编写代码时不确定要创建什么类型的对象,也不确定要调用什么样的方法,这些都希望通过运行时传递的参数来决定,该机制叫做动态编程技术,也就是反射机制
- 通俗来说,反射机制就是用于动态创建对象并且动态调用方法的机制
获取Class对象的方式
- 使用数据类型.class的方式可以获取对应类型的Class对象
- 使用引用/对象.getClass()的方式可以获取对应类型的Class对象
- 使用包装类.TYPE的方式可以获取对应基本数据类型的Class对象
- 使用Class.forName()的方式来获取参数指定类型的Class对象
- 使用类加载器ClassLoader的方式获取指定类型的Class对象
常用的方法
方法声明 | 功能介绍 |
---|---|
static Class<?> forName(String className) | 用于获取参数指定类型对应的Class对象并返回 |
T newInstance() | 用于创建该Class对象所表示类的新实例 |
Constructor类
基本概念
- java.lang.reflect.Constructor类主要用于描述获取到的构造方法信息
Class类的常用方法
方法声明 | 功能介绍 |
---|---|
Constructor getConstructor(Class<?> … parameterTypes) | 用于获取此Class对象所表示类型中参数指定的公共构造方法 |
Constructor<?>[] getConstructors() | 用于获取此Class对象所表示类型中所有的公共构造方法 |
Constructor类的常用方法
方法声明 | 功能介绍 |
---|---|
T newInstance(Object… initargs) | 使用此Constructor对象描述的构造方法来构造Class对象代表类型的新实例 |
int getModifiers() | 获取方法的访问修饰符 |
String getName() | 获取方法的名称 |
Class<?>[] getParameterTypes() | 获取方法所有参数的类型 |
Field类
基本概念
- java.lang.reflect.Field类主要用于描述获取到的单个成员变量信息
Class类的常用方法
方法声明 | 功能介绍 |
---|---|
Field getDeclareField(String name) | 用于获取此Class对象所表示类中参数指定的单个成员变量信息 |
Field[] getDeclaredFields() | 用于获取此Class对象所表示类中所有成员变量信息 |
Field类的常用方法
方法声明 | 功能介绍 |
---|---|
Object get(Object obj) | 获取参数对象obj中此Field对象所表示成员变量的数值 |
void set(Object obj, Object value) | 将参数对象obj中此Field对象表示成员变量的数值修改为参数value的数值 |
void setAccessible(boolean flag) | 将实参传递true时,则反射对象在使用时应该取消Java语言访问检查 |
int getModifiers() | 获取成员变量的访问修饰符 |
Class<?> getType() | 获取成员变量的数据类型 |
String getName() | 获取成员变量的名称 |
Method类
基本概念
- java.lang.reflect.Method类主要用于描述获取到的单个成员方法信息
Class类的常用方法
方法声明 | 功能介绍 |
---|---|
Method getMethod(String name, Class<?>… parameterTypes) | 用于获取该Class对象表示类中名字为name参数为parameterTypes的指定公共成员方法 |
Method[] getMethods() | 用于获取该Class对象表示类中所有公共成员方法 |
Method类的常用方法
方法声明 | 功能介绍 |
---|---|
Object invoke(Object obj, Object… args) | 适用对象obj来调用此Method对象所表示的成员方法,实参传递args |
int getModifiers() | 获取方法的访问修饰符 |
Class<?> getReturnType() | 获取方法的返回值类型 |
String getName() | 获取方法的名称 |
Class<?>[] getParameterTypes() | 获取方法所有参数的类型 |
Class<?>[] getExceptionTypes() | 获取方法的异常信息 |
获取其他结构信息
方法声明 | 功能介绍 |
---|---|
Package getPackage() | 获取所在的包信息 |
Class<? super T> getSuperclass() | 获取继承的父类信息 |
Class<?>[] getInterfaces() | 获取实现的所有接口 |
Annotation[] getAnnotations() | 获取注解信息 |
Type[] getGenericInterfaces() | 获取泛型信息 |