JAVASE
2021/7/25 11:38:36
本文主要是介绍JAVASE,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
JAVASE
完成任务后, 您可以点击图标, 修改为已完成.
基础语法
Java的跨平台
- 基于JVM,每一个系统都有对应的JVM
- Java语言是跨平台的,但是JVM不是跨平台的
JDK/JRE/JVM
- JDK:Java开发工具包,包含了JRE和开发工具
- JRE:Java运行环境,包含了JVM和核心类库
- JVM:Java虚拟机,是Java实现可移植性的前提
入门程序
- 编译命令:javac -d 文件的存放路径 要编译的Java文件
- 运行命令:java -cp class文件的存放路径 包名.类名
- 每一个Java文件中可以存放多个类,但是只能有一个公共类
- 每一个类在编译完成之后都会产生一个class文件,所以class文件名和类名对应
关键字
- 一共是53个关键字
- 2个目前没有使用—保留字
- 所有的关键字都是小写的
标识符
-
命名规则
- 由字母、数字、_、$组成
- 数字不能开头
- 不能使用关键字
- 大小写敏感
- 见名知意
-
驼峰命名法
- 类名/接口名:每个单词的首字母都需要大写,其余字母小写
- 方法名/变量名:第一个单词的首字母小写,其余单词的首字母大写
- 常量名:所有的字母都要大写,多个单词之间用_隔开
- 包名:所有的字母都要小写,多个单词之间用 . 隔开
注释
-
单行注释 // 注释文字
-
多行注释 /注释文字/
-
文档注释 /*注释文字/
- 可以利用javadoc命令将注释文字提取出来形成文档
- 只能提取公共类
字面量
-
整数常量
- 所有的整数
-
小数常量
- 所有的小数
-
字符常量
- 将一个字母、数字、符号用 ''标志起来
-
字符串常量
- 将一个或者多个字符用""标志起来
-
布尔常量
- true/false,用于表示逻辑值
-
空常量
- null
进制
-
二进制
- 0-1两个基本元素
- 满2进1, 1+1=10
- 从JDK1.7开始,用0b/0B开头作为标志
-
八进制
- 0-7八个基本元素
- 满8进1,7+1=10
- 用0开头作为标志
-
十进制
- 0-9十个基本元素
- 满10进1,9+1=10
- 代码中,数字默认就是十进制
-
十六进制
- 0-9,A-F十六个基本元素
- 满16进1,9+1=a, a+1=b f+1=10
- 用0x开头作为标志
进制的转换
-
十进制->二进制
- 将数字除以2,取余数,将余数倒排
-
二进制->十进制
- 从低位次开始,按位次乘以2的位次次幂,然后求和
-
十进制->任何进制
- 将数字除以对应的进制,取余数,将余数倒排
-
任何进制->十进制
- 从低位次开始,按位次乘以赌赢的进制次幂,然后求和
-
八进制->二进制
- 每一位八进制产生三位二进制,如果不足三位,补0
-
二进制->八进制
- 从低位开始,每三位二进制产生一位八进制,如果不足三位,补0
-
十六进制->二进制
- 每一位十六进制产生四位二进制,如果不足四位,补0
-
二进制->十六进制
- 从低位开始,每四位二进制产生一位十六进制,如果不足四位,补0
变量
- 要素:数据类型、变量名、变量值
- 变量先定义后使用
- 变量必须先赋值后使用
- 变量在哪儿定义在哪儿使用
数据类型
-
基本数据类型
-
数值型
-
整数型
-
字节型 byte
- 1个字节
- -27~27-1 — -128~127
-
短整型 short
- 2个字节
- -215~215-1 — -32768~32767
-
整型 int
- 4个字节
- -231~231-1 — 大概-1010~1010
- Java中,整数默认为int
-
长整型 long
- 8个字节
- -263~263-1 — 大概-1018~1018
- 需要以L/l作为结尾
-
-
浮点型
-
单精度 float
- 4个字节
- 大概-1038~1038
- 需要以f/F作为结尾
-
双精度 double
-
8个字节
-
大概-10308~10308
-
Java中,小数默认为double
-
注意:科学计数法
- 十进制科学计数法:aeb表示a*10^b
- 十六进制科学计数法:0xapb表示a*2^b
-
-
-
注意:Java中的数值型都是有符号
-
-
字符型
-
char
- 2个字节
- 0-65535
- Java中,char类型的数据是以UTF-16的编码来进行存储
-
-
布尔型
-
boolean
- 值:true/false
- 表示逻辑值
- boolean的内存是不确定,随着系统和JDK的版本来确定
-
-
-
引用数据类型
- 数组 []
- 类 class
- 接口 interface
数据类型的转换
-
隐式转换
- 自动类型转换
- 小类型转化为大类型
- 整数转化为小数会产生精度损失
- char类型可以自动提升为int
-
显式转换
- 强制类型转换
- 大类型转化为小类型
- 小数转化为整数会舍弃小数部分
- 大的数字转化为小的类型的时候会产生精度损失
运算符
-
算术
-
-
-
- / % ++ –
-
-
-
整数运算完成之后的结果一定是整数
-
小的类型和大的类型运算,结果应该是大的类型
-
byte/short/char在运算之后的结果自动提升为int
-
对于小数而言,运算结果是不精确
-
除以0
- 整数/0 — ArithmeticException
- 非零小数/0 非零数字/0.0 Infinity
- 0.0/0 0/0.0 0.0/0.0 NaN
-
取余运算的结果的符号看的是%左边的数字的符号
-
++/–
- 如果在变量之前,先自增/自减,然后参与后续运算
- 如果在变量之后,先将值取出来参与后续运算,然后自增/自减
- byte/short/char可以参与自增运算,而且结果类型是原来的类型
-
-
赋值
- = += -= *= /= %= &= |= ^= <<= >>= >>>=
- 除了=以外,其余的符号都要求变量先有值,才能使用
- byte/short/char可以参与赋值运算
- 注意:赋值运算的连等
-
关系
- == != > < >= <=
- 运算结果一定是boolean类型
- 比较值的关系
-
逻辑
-
& | ! ^ && ||
-
^的运算规则:相同为假,不同为真
-
&&和||的短路特性
- 如果前边为false,&&后边的表达式就不再运算
- 如果前边为true,||后边的表达式就不再运算
- ||在前可以把后边的&&给短路掉
-
-
位
-
& | ^ << >> >>> ~
-
针对的整数的补码进行运算,那么运算结果也一定是补码
-
数据在计算机中是以补码形式存在
-
任何一个数据都有原码、反码、补码形式
- 对于正数而言,原反补三码一致
- 对于负数而言,反码是在原码的基础上最高位不变,其余位1<->0;补码是在反码的基础上+1
-
-
& | ^:将数据转化为补码之后进行按位运算
-
&: 0&a=0 a&1=1或0
-
|: 0|a=a
-
:aa=0 0^a=a abb=a
-
交换值
-
追尾法
- 利用第三方变量来交换两个变量的值
- 局限性比较小,可以适用于任何类型
- 额外耗费空间,运行效率相对较低
-
加减法
- 只能运算数值型
- 效率高于追尾而低于亦或
- 尽量减少对小数使用加减法交换值
-
亦或法
- 效率最高
- 只能适用于整数交换,局限性最大
-
-
<<:在一定范围内,左移几位就是乘以2的几次方
-
:在一定范围内,右移几位就是除以2的几次方
- 正数:右移越移越小,最小到0
- 负数:右移越移越大,最大到-1
-
:无论正负,空出的最高位一律补0
-
实际上移动的(位数%32)
-
:i = -i-1
-
-
三元
- 逻辑值?表达式1:表达式2;
- 执行顺序:如果逻辑值为true,则执行表达式1;反之执行表达式2
- 表达式1和表达式2的结果类型要一致或者能够自动转化
- 运算完成之后一定有一个结果—这个结果可以用一个变量来接住
-
运算符的优先级:一元>二元>三元>赋值
- () ~ ++ – ! 算术 << >> >>> 关系 逻辑 & | ^ 三元 赋值
流程控制
-
顺序结构
- 代码从上到下从左到右依次编译运行
-
分支结构
-
判断结构
-
if
- 适合于单个条件的判断
-
if-else
-
if-else if
- 多个条件分部筛选
-
-
选择结构
-
switch-case
- switch()的值类型:byte/short/char/int,从JDK1.5开始允许使用枚举,从JDK1.7开始允许使用String
- 如果每一个case之后都有break,那么case的顺序不影响结果
- 如果有一个或者多个case之后没有break,那么从匹配的选项开始依次往下执行,直到遇到break或者是switch结束才会停止执行,所以此时case的顺序会影响结果
-
-
-
循环结构
-
while
- 适用于次数不固定或者变化不规律的场景
-
do-while
- 循环体至少执行一次
-
for
- 使用次数固定或者步长有规律的场景
-
循环的要素:定义循环变量,控制循环条件,改变循环变量
-
注意:循环的嵌套
-
-
break和continue
- break:可以用于选择结构和循环结构中,用于终止当前的一层结构
- continue:只能用于循环结构,表示跳过本次的一层循环继续下次循环
- 支持标号形式
数组
-
格式
- 数据类型[] 数组名 = new 数据类型[数组的大小];
- 数据类型[] 数组名 = new 数据类型[]{元素1, 元素2…};
- 数据类型[] 数组名 = {元素1, 元素2…};
-
数组的内存
- 数组是存储在堆内存中
- 在堆内存中会自动赋予默认值
- 栈内存存储的是这个数组的地址
-
数组的应用
-
获取数组的元素
- 数组名[下标]
-
获取数组的长度
- 数组名.length
-
遍历数组
- 通过下标遍历
-
获取最值
- 定义变量记录最大值
- 记录最大值的下标
-
数组元素的排序
-
冒泡排序
- 时间复杂度:O(n^2)
- 空间复杂度:o(1)
-
选择排序
- 时间复杂度:O(n^2)
- 空间复杂度:o(1)
-
Arrays.sort
- 时间复杂度:O(nlogn)
-
-
元素的查找
-
元素无序—遍历
-
元素有序—二分查找
- 时间复杂度:O(logn)
- 空间复杂度:o(1)
-
-
数组的反转
- 首尾互换
-
数组的复制
-
System.arraycopy(原数组, 复制的起始位置, 目标数组, 存放的起始位置, 复制的元素的个数);
-
Arrays.copyOf(原数组, 变化之后的长度);
- 底层实际上是调用了System.arraycopy
- 数组的扩容之后的地址一定发生了改变
-
-
-
时间复杂度:程序中必然会执行的代码的执行时间认为是单位1,执行这个单位1所需要的次数
-
空间复杂度:程序执行过程中,额外开辟的内存空间
二维数组
-
格式
- 数据类型[][] 数组名 = new 数据类型[包含的一维数组的个数][每个一维数组的长度];
- 数据类型[][] 数组名 = new 数据类型[包含的一维数组的个数][];
- 数据类型[][] 数组名 = {{}, {}, {}…};
-
二维数组的内存
- 二维数组存储在堆内存中
- 二维数组的每一个位置上存储的是一维数组的地址
- 如果一个位置上没有指定一维数组,那么默认值为null
方法
-
格式
- 修饰符 返回值类型 方法名(参数列表){方法体; return 返回值;}
- 如果一个方法没有返回值,返回值类型定义为void
-
意义
- 提高代码的复用性
- 便于团队的合作开发
- 使代码的结构更加清晰
-
方法的传参
- 形参:定义方法的时候()定义的变量
- 实参:调用方法的时候传入的数据
- 对于基本类型而言,传参传递的是实际值,所以在另一个方法中改变这个参数的值不会影响原来方法的数据
- 对于引用类型尔雅,传参传递的是地址。如果地址不发生改变,则影响原来方法中的对象;如果地址放生改变,则不影响原来的对象
-
方法的重载
- 在同一个类中,存在方法名一致而参数列表不同的方法
- 参数列表不同指的是参数的个数或者是对应位置上的参数类型
- 和修饰符、返回值类型、异常没有关系
-
方法的重写
- 在父子类中存在了方法签名一致的非静态方法
- 如果返回值类型是基本类型或者是void,则子类在重写方法的时候的返回值类型要一致
- 如果返回值类型是引用类型,那么子类重写的方法的返回值类型是父类方法的方法返回值类型的子类,或者与父类方法的返回值类型一致
- 如果父类的方法抛出了异常,那么子类在重写的时候的异常不能超过父类异常的范围,而且指的是编译时异常
- 子类重写的方法的权限修饰符的范围要大于等于父类方法的权限修饰符的范围
-
方法的递归
- 在方法中调用了方法本身
- 如果递归次数过多会出现栈溢出错误—StackOverFlowError
面向对象
面向对象与面向过程的比较
- 面向过程注重流程中的每一步
- 面向对象注重的对象,只要有了对象,就可以获取对象身上的一切功能
- 对于简单事务,适合于用面向过程;对于复杂事务,建议使用面向对象
- 面向对象是基于面向过程
类和对象的关系
- 类是对象的概括
- 对象是类的实例化
- 在类中,属性是一种特征,方法是一种行为
成员变量和局部变量
-
定义位置
- 成员变量定义在类内;局部变量定义在代码块中
-
作用范围
- 成员变量作用在整个类内;局部变量作用在当前的代码块/语句中
-
内存位置
- 成员变量存储在堆内存中,并且堆内存中有默认值;局部变量是存储在栈内存中,没有默认值
-
生命周期
- 成员变量是在对象被创建的时候出现,在对象被回收的时候被销毁;局部变量是在语句执行的时候创建,在代码块执行完成之后被释放
构造方法
- 特点:与类同名而没有返回值类型
- 作用:创建对象,初始化属性
- 可以写return,用于规避不合法的情况
this关键字
-
代表当前在活动的对象的引用,可以认为是一个虚拟对象
-
用于在本类中调用本类中的非静态方法和非静态属性
-
this语句
- 在本类的构造方法中调用本类对应形式的构造方法
- 必须放在构造方法的首行
代码块
-
局部代码块
- 定义方法中用{}包起来的代码
- 意义:限制变量的使用范围以及生命周期,以提高栈内存的利用率
-
构造代码块
- 定义在类中用{}包起来的代码
- 在创建对象的时候先于构造方法执行
面向对象的特征
-
封装
-
体现形式:方法、属性的私有化、内部类
-
优势
- 提高代码的服用
- 保证数据的合法性
-
-
继承
-
类用extends来继承另一个类
-
类和类之间是单继承
-
单继承和多继承的比较
- 单继承明确调用的方法
- 多继承能够更好的提高代码的复用性
-
通过继承,子类可以继承父类所有的方法和属性,但是子类只能使用父类中的一部分方法和属性
-
意义
- 提高代码的复用性
- 避免调用方法产生混乱
-
-
多态
-
根据时期
-
编译时多态
- 方法的重载
-
运行时多态
-
向上造型
- 用父类/接口声明,用子类/实现类来创建
- 对象能干什么看的是父类,怎么干看的是子类
-
方法的重写
-
基于继承
-
-
-
根据形式
-
行为多态
- 方法的重载
- 方法的重写
-
对象多态
- 向上造型
-
-
意义
- 使代码的调用形式更加的灵活和统一
- 配合反射实现解耦
-
super关键字
-
在子类中代表父类对象的引用
-
在子类中调用父类中的方法和属性
-
在创建子类对象的时候必然先创建父类对象
-
super语句
- 如果子类的构造方法中没有手动指定super语句,那么默认添加无参的super
- 利用super语句调用父类中对应形式的构造方法
- 如果父类中没有提供无参构造,那么子类的构造方法就必须提供对应形式的superu语句
- super语句必须放在子类构造方法的第一行
权限修饰符
-
public
- 本类中、子类中、同包类中、其他类中
-
protected
- 本类中、子类中、同包类中
-
默认
- 本类中、同包类中
-
private
- 本类中
-
在子类中使用的时候,使用哪个子类对象,就必须是在对应的子类中使用
static
-
静态变量
- 在类加载的时候加载到方法区
- 在方法区中赋予了默认值
- 静态变量先于对象出现,习惯上通过类名来调用
- 对象存的是静态变量的地址,所以所有的对象共享这个静态变量
- 静态变量只能定义在类中
-
静态方法
- 随着类的加载而加载到方法区
- 在方法区中没有执行只是存储
- 在调用的时候到栈内存中执行
- 静态方法是先于对象存在,习惯上通过类名来调用
- 静态方法可以重载
- 静态方法可以被继承
- 静态方法不能重写
- 父子类中可以存在方法签名一致的静态方法—隐藏
- 如果父子类中存在方法签名一致的方法,要么都是静态方法,要么都是非静态方法
-
静态代码块
-
在类中用static{}包起来的代码
-
在类第一次被真正使用的时候执行一次
-
执行顺序
- 父类的静态
- 子类的静态
- 父类的非静态
- 子类的非静态
-
-
静态内部类
final
-
常量
-
对于基本类型,指的是实际值不可变
-
对于引用类型,指的是地址不可变,属性值可以改变
-
成员常量
- 在对象创建完成之前给值
-
静态常量
- 在类加载完成之前给值
-
-
最终方法
- 可以重载
- 可以被继承
- 不能被重写/隐藏
-
最终类
- 不能被继承
abstract
-
抽象类
- 不一定有抽象方法
- 不能被实例化
- 有构造方法
- 抽象类中可以定义一切的属性和方法
- 子类继承抽象类之后需要重写所有的抽象方法,除非这个子类也是抽象类
- 抽象类一定不是最终类
-
抽象方法
- 可以被重载
- 必然被继承,必然被重写
- 不能用static/final/private修饰
- 如果抽象类的权限修饰符是默认的,那么要求父子类同包
interface
- 一个类用implements关键字来实现一个类
- 一个类可以实现多个接口
- 接口和接口之间是多继承的关系
- 接口中所有的方法都是抽象方法,抽象方法默认使用public abstract修饰
- 接口中没有构造方法
- 类实现接口之后需要重写所有的抽象方法
- 接口中定义的属性默认是使用public static final修饰
内部类
-
方法内部类
- 定义在方法中的类
- 只能在定义它的方法中使用
- 方法内部类中不可以静态变量和静态方法,但是可以定义静态常量
- 方法内部类在使用当前方法中的数据的时候,要求这个数据是一个常量
- 方法内部类可以使用当前外部类中的属性和方法
-
成员内部类
- 定义在类内方法外
- 不可以定义静态变量和静态方法,但是可以定义静态常量
- 可以使用外部类中的一切属性和方法
-
静态内部类
- 用static修饰的内部类
- 可以定义静态变量和静态方法
- 不可以使用当前外部类中的非静态属性和非静态方法
- 只能外部类中的静态属性和静态方法
-
匿名内部类
- 匿名内部类本质上是继承了对应的类或者是实现了对应的接口
- 任何一个类,只要不是最终类,一定可以存在匿名内部类形式
- 任何一个接口一定可以产生匿名内部类形式
包
- 声明包用package
- 导入包用的import
- 在Java文件中只能有1个package语句,而且这句话必须放在Java文件的第一行
-
- 表示导入当前包下的所有的类而不包括子包下的类
- 如果使用的是java.lang或者是同包中的类,可以不用导包
垃圾分代回收机制
- 针对的是堆内存
- 堆内存在不确定的某个时刻被GC扫描进行对象的回收
- 对象创建的时候是放到新生代
- 在新生代中的伊甸园区经过一次扫描如果依然存在,则挪到幸存区
- 在幸存区经过多次扫描如果依然存在,则挪到老生代
- 老生代的扫描频率要远低于新生代
- 初代回收(minor gc):发生在新生代的回收
- 完全回收(full gc):发生在老生代的回收
API
Object
-
是java中的顶级父类
-
任何一个对象都可以用Object对象来接住
-
重要方法
- getClass:获取对象的实际类型,返回是一个Class对象
- equals:比较两个对象是否相等。在比较的时候默认比较的是地址,一般需要重写equals方法
- toString:将对象转化为字符串形式。打印一个对象的时候一般默认是调用了对象的toString方法
String
- 代表字符串的类
- 是一个最终类,不可以被继承
- 字符串是一个常量,是存储在常量池的,被共享的
- 注意字符串的拼接运算:+默认使用的是StringBuilder中的append方法
- 字符串在Java底层是以字符数组形式来进行存储
- 字符串的哈希码是固定不变的
StringBuilder/StringBuffer
- 底层是以字符数组形式来存储数据
- StringBuilder是一个线程不安全的类,StringBuffer是一个线程安全的类
- StringBuffer之所以能保证线程安全是因为底层采用了同步方法的机制
Pattern
-
用于指定规则的类
-
匹配格式
- [abc] 表示a或者b或者c
- [^abc] 除了a/b/c
-
预定义字符
- . 任意字符
- \d 任意数字
- \D 非数字
- \s 空白字符
- \S 非空白字符
- \w 单词字符-字母、数字、_
- \W 非单词字符
-
数量词
-
-
=1
-
- ? <= 1
-
-
= 0
-
- {n} =n
- {n,} >= n
- {n,m} n <= x <= m
- 注意:每一个字符或者捕获组之后只能使用一个数量词
-
-
捕获组
- 将一个或者多个符号看作一个整体进行匹配
- 捕获组的编号:从(出现的位置开始计算
- \n 表示引用编号为n的捕获组
包装类
-
对于每种基本类型都提供了对应的类形式
- byte-Byte
- short-Short
- int-Integer
- long-Long
- float-Float
- double-Double
- char-Character
- boolean-Boolean
- void-Void
-
注意:所有的数值型的包装类都有一个对应父类是Number
-
所有的数值型以及Boolean都提供了将字符串转化为对应的类型的方法
-
所有的包装类对象的哈希码是固定不变的
-
自动封箱拆箱
数学类
-
Math
- 最终类,构造方法私有化,不可创建对象
- 提供了大量的静态方法,允许对基本类型进行初等的数据运算
- 在计算小数的时候不精确
-
BigDecimal
- 用于精确计算的类
- 在精确计算的时候要求参数以字符串形式传入
-
BigInteger
- 用于存储任意大小的整数的类
- 在存储的时候需要以字节数组或者是字符串形式来传递
日期类
-
Date
-
表示日期的类
-
提供了大量的方法,但是大部分已过时
-
掌握字符串和日期之间的转换:SimpleDateFormat
- parse:将字符串转化为日期
- format:将日期转化为字符串
- 在转化的时候需要指定转化格式
-
-
Calendar
- 表示日历的类
- 提供了大量的属性和方法来操作时间
异常
-
是java中一套用于问题的反馈和处理的机制
-
Throwable
-
Error
- 表示错误
- 一旦出现不可处理
-
Exception
-
编译时异常(已检查异常)
- 在编译的时候就已经出现,要求必须处理
-
运行时异常(未检查异常)
- 继承RuntimeException
- 在运行的时候才会出现,出现之后可以处理可以不处理
-
-
-
自定义异常
- 继承一个异常类
- 如果继承的是Exception或者是其他的编译时异常,那么这个自定义异常就是一个编译时异常
- 如果继承的是RuntimeException或者是其子类,那么就是一个运行时异常
-
异常的处理方式
-
继续向上抛出-在方法中用throw抛出该异常对象,在方法签名上利用throws来生命
-
进行捕获处理
- 如果每一个异常的处理方式都不一样,利用多个catch来分别捕获分别处理
- 如果所有异常的处理方式都一样,捕获父类异常统一处理
- 如果不同异常的处理方式进行了分组,那么将同一组的异常用|隔开,这种方式是从JDK1.7开始
-
-
finally
- 无论出现异常与否,都必须执行一次
集合
-
是Java中用于存储多个数据的容器,该容器的大小是不固定
-
顶级接口Collection
-
列表List
-
保证元素的存储顺序,允许存储重复元素
-
顺序表ArrayList
- 底层基于数组
- 默认初始容量是10
- 每次默认增加一半,底层基于右移
- 内存空间连续
- 增删相对复杂,查询相对简单
- 线程不安全
-
链表LinkedList
- 底层基于节点
- 内存空间不连续
- 增删相对简单,查询相对复杂
- 线程不安全
-
向量Vector
-
底层基于数组
-
默认初始容量是10
-
默认增加一倍,底层是基于三元运算
-
内存空间连续
-
增删相对复杂,查询相对简单
-
线程安全
-
栈Stack
- 遵循先进后出
- 入栈:将元素放入栈中
- 出栈:将元素从栈中取出
- 栈顶元素:最后放入栈中的元素
- 栈底元素:最先放入栈中的元素
-
-
-
散列集合Set
-
元素不可重复,底层存储是无序的
-
HashSet
-
底层基于哈希码来存储元素
-
不保证元素存入顺序
-
底层基于HashMap存储
-
线程不安全
-
LinkedHashSet
- 基于哈希码加链表结构
-
-
TreeSet
- 在存储元素的时候会进行排序
- 要求存储的元素对应的类必须实现Comparable接口
-
-
队列Queue
- 先进先出
- 常用实现类:LinkedList
-
比较器
-
Comparable
- 需要重写compareTo方法,实现它的类产生的对象可以实现自然排序
-
Comparator
- 如果需要对某一个集合或者数组单独排序,需要重写Comparator中的compre方法
迭代器
-
Iterable
- 实现这个接口的类产生的对象可以被增强for循环遍历
-
Iterator
- 在迭代遍历集合的时候,是将该集合做一个复制,然后在复制过程中对每一个元素进行标记,表示该元素是否存在。
- 在迭代过程中不允许增删原集合
-
Enumeration
- 最古老的迭代器
- 现在一般是利用Vector类中的elements方法来产生
映射
-
顶级接口Map
-
HashMap
- 底层是基于键的哈希码来进行存储
- 底层结构是用的数组+链表
- 底层数组的默认大小是16
- 数组的每一个位置称之为是一个桶
- 每一个桶中维持一个链表结构
- 在存储元素的时候是先计算键的哈希码,然后根据哈希码分配到不同的桶中,根桶中的键一一比较,如果一致则舍弃,如果不一致,则插到这个链表的最前面
- 在元素个数比较多的情况下,每一个桶中维持的链表会比较长,会导致效率降低,所以需要扩容
- 是否扩容依赖的是加载因子
- 默认加载因子是0.75f
- 当使用的桶的个数超过桶的总数*加载因子,就需要扩容
- 每次默认增加一倍
- 扩容之后,需要重新计算所有元素的哈希码重新进行分布,这一步称之为rehash
- 如果桶数量较小会导致频繁发生扩容和rehash
- 如果加载因子过小,也会导致频繁扩容和rehash,同时还会浪费空间
- 如果加载因子过大,会导致每一个桶中的链表过长从而降低效率
- 允许键或者值为null
- 异步式线程不安全
-
Hashtable
-
不允许键或者值为null
-
默认初始容量是11
-
默认加载因子是0.75f
-
同步式线程安全
-
Properties
-
是一个可以持久化的映射
-
键和值默认是String
-
可以store方法存储到硬盘上
- Properties对象一定要存到.properties文件中
- properties文件作为配置文件使用
- properties文件中不存储中文,一旦放入中文会转化为对应的编码
- Properties文件默认编码是西欧编码
-
可以通过load方法反持久化回来
-
-
-
-
键不可重复
-
每一个键对应一个值 - 键值对
-
Map.Entry:代表键值对的接口
-
遍历映射的方式
- 先获取所有的键,然后根据键获取值 - keySet()
- 直接获取所有的键值对 - entrySet()
File
- 代表文件或者目录的类
- 所表示的文件后者目录在计算机中不一定真实存在
- 文件操作的时候大多数情况下需要使用递归
IO
-
是java中一套用于数据传输的机制
-
传输方向
- 输入流:数据从外部流向程序
- 输出流:数据从程序流向外部
-
传输形式
- 字节流
- 字符流
-
四个基本流
-
InputStream
- FileInputStream
- System.in
- ObjectIntputStream
-
OutputStream
- FileOutputStream
- System.out
- System.err
- PrintStream
- ObjectOutputSteam
-
Reader
-
InputStreamReader
- 将字节转化为字符
- FileReader
-
BufferedReader
-
-
Writer
-
OutputStreamWriter
- 将字符转化为字节
- FileWriter
-
BufferedWriter
-
PrintWriter
-
-
-
来源/目的地
- 硬盘
- 内存
- 网络
- 输入设备
-
流的异常处理
- 流对象需要在try之外声明并且赋值为null,然后再try之内初始化
- 在关流之前需要判断流对象是否为空
- 为了防止关流失败占用资源,需要将刘对象设置为null
- 如果是字符输出流,那么为了关流失败以防有数据死在缓冲区中,所以在关流之前需要手动flush
-
序列化/反序列化
-
序列化:将对象转化为字节数组的过程
- 持久化是指对象保存到硬盘上
-
反序列化:将字节数组转化为对象的过程
-
注意问题
- 一个对象要想被序列化必须实现Serializable接口,这个接口中没有任何的方法和属性,仅仅用于标记
- 用static/transient修饰的属性不会被序列化
- 每一个可以被序列化的类中有一个版本号-serialVersionUID,如果没有手动版本号会根据当前类中的方法和属性自动计算一个版本号,所以类中每发生一次变动就会重新计算版本号。如果手动指定版本号,则不会发生变化。对象在反序列化的时候需要比较对象持有的版本号和类中定义的版本号是否一致,如果一直才允许反序列化。所以版本号的作用是用于防止类在产生变动的情况下已经序列化的对象无法反序列化回来
-
线程
-
进程
- 是计算机的CPU在执行的任务
- 是进程的子任务
-
顶级父类Thread
-
定义线程
- 继承Thread类,重写run方法,然后通过start方法启动
- 实现Runnable接口,重写run方法,然后创建Thread对象,利用Thread对象来启动线程
- 实现Callable接口,重写call方法
-
线程并发安全
-
多个线程同时执行,由于线程之间的执行是相互抢占并且抢占是发生在线程执行的每一步,所以会导致出现不符合实际的情况
-
synchronized
-
同步代码块
-
需要锁对象
- 共享资源
- 类的字节码
- this
-
同步
- 同一时间内某段代码只允许一个线程执行
-
异步
- 同一时间内某段代码允许多个线程同时执行
-
-
同步方法
- 非静态方法的锁对象是this
- 静态方法的所对象是当前类
-
死锁
- 锁对象不统一并且多个锁之间形成了嵌套
-
-
-
等待唤醒
- 通过wait方法让当前线程陷入等待
- 通过notify唤醒等待的线程,每次只能唤醒一个
- 通过notifyAll唤醒所有的线程
-
线程的状态
-
创建
-
就绪
-
执行/活跃
-
挂起/阻塞
-
结束/消亡
-
状态转化
- 就绪->执行
- 执行->阻塞
- 阻塞->就绪
- 就绪->阻塞
-
-
守护线程
- 当被守护的线程接收,守护线程无论完成与否都要结束
- 以最后一个被守护的线程作为标准
-
线程的优先级
- 1~10
- 理论上数字越大优先级越高,意味着抢占CPU的概率越大
- 相邻两个优先级的差异性非常不明显
- 如果优先级相差到5个单位及以上,才略微明显
套接字
-
用于网络进行通信的机制
-
UDP
-
不建立连接
-
不可靠
-
传输速率相对较快
-
会对数据进行封包,每个包不超过64KB
-
DatagramSocket:用于发送端和接收端
-
发送端
- 创建套接字对象
- 准备数据包,将数据封包
- 绑定地址,发送数据
- 关流
-
接收端
- 创建套接字对象,绑定监听的端口号
- 准备数据包
- 接受数据
- 关流
- 解析数据包
-
-
DatagramPacket:数据包
-
-
TCP
-
建立连接
-
可靠
-
三次握手
-
传输速率相对较慢
-
不封包,理论上不限制数据大小
-
客户端Socket
- 创建套接字对象
- 发起连接
- 获取输出流,写出数据
- 禁用输出流
- 关流
-
服务器端ServerSocket
- 创建套接字对象,绑定端口号
- 接受连接,获取Socket对象
- 获取输入流,读取数据
- 禁用数据流
- 关流
-
JDK1.5的特性
-
自动封箱拆箱
-
自动封箱
- 将基本类型直接赋值给对应的引用类型
- 自动封箱调用的是对应类身上的valueOf方法
- 对于正数类型,在自动封箱的时候有一个范围判断 - -128~127
-
自动拆箱
- 将引用类型直接赋值给对应的基本类型
- 自动拆箱调用的对应对象身上的***Value方法
-
-
增强for循环
- 要求遍历的对象对应的类必须实现Iterable接口
- 本质上是一种迭代遍历
- 在遍历过程中不允许增删原集合
-
泛型
-
参数化类型-ParameterizedType
-
泛型的擦除
- 用具体类型替换泛型
- 发生在编译期
-
自定义泛型
-
泛型的边界
-
上限
- ? extends 类/接口
-
下限
- ? super 类/接口
-
-
-
静态导入
- imprt static 包名.类名.静态方法名
- 可以提高加载效率
- 降低可读性
-
可变参数
- 用 … 定义
- 本质上是一个数组
- 可以传入任意个数的参数
- 定义的时候必须放在参数列表的末尾
-
枚举
- 用enum定义
- 在取值情况相对固定并且能够一一列举的情况下使用
- 枚举常量必须定义在枚举类的第一行
- 枚举类中的构造方法只能是私有的
- 枚举类中可以定义任意的属性和方法,也可以定义抽象方法
- 从JDK1.5开始,switch-case支持枚举
- 顶级父类java.lang.Enum
-
反射
-
获取类的字节码,从而分析类的信息
-
获取Class的方式
- 类名.class
- 对象.getClass()
- Class.forName(类的全路径名)
-
Class
- 代表字节码的类
-
Field
- 代表属性的类
-
Method
- 代表方法的类
-
Constructor
- 代表构造方法的类
-
Package
- 代表包的类
-
Annotation
- 代表注解的类
-
-
动态代理
- 利用Proxy产生对象的代理对象
- 在代理对象中可以对一些进行修改
-
注解
-
顶级父类Annotation
-
用@interface定义
-
属性:数据类型 属性名() default 默认值
-
可以使用的数据类型
- 基本类型
- String
- Class
- 枚举
- 注解
- 以上类型对应的一维数组
-
-
在赋值的时候如果属性名为value并且只有一个属性,那么在赋值的时候可以省略名称
-
元注解
-
@Target
- 定义注解的使用位置
-
@Retention
- 定义注解的生命周期
-
@Documented
- 控制注解是否生成到文档中
-
@Inherited
- 表示该注解能否被继承
-
-
-
内省
内存
栈内存
- 执行代码块
- 每一个线程独有的
堆内存
-
存储对象
-
划分
-
新生代
- 伊甸园区
- 幸存区
-
老生代
-
-
所有线程共享的
方法区
-
存储类信息
-
划分
-
静态常量池
- 存储类信息
-
运行时常量池
- 存储字面量和自定义常量
-
-
所有线程所共享
本地方法栈
- 执行本地方法
- 每一个线程所独有的
寄存器
- 用于控制程序的执行指令的
- 每一个线程所独有的
这篇关于JAVASE的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-19JAVA分布式id教程:轻松入门与实践
- 2024-11-19Java高并发教程:入门与实践指南
- 2024-11-19JAVA高并发直播教程:新手入门指南
- 2024-11-19Java高并发直播教程:入门与实践指南
- 2024-11-19Java微服务教程:初学者快速入门指南
- 2024-11-19JAVA微服务教程:新手入门的详细指南
- 2024-11-19Java微服务教程:从零开始搭建你的第一个微服务应用
- 2024-11-19Java项目开发教程:初学者必备指南
- 2024-11-19Java项目开发教程:新手快速入门指南
- 2024-11-19Java项目开发教程:零基础入门到实战