JavaSE
引言
本文是对Java基础的一些个人总结,适合小白在进行基本的学习后所复习的总结文档,授人以渔不如授之以渔,在Java的学习中需要多敲多理解,所以本文中代码数量占少,所需要理解的地方居多。本文为个人理解,如有需要订正之处,敬请指出,本人邮箱1209110434@qq.com,在之后也会更新并发编程,集合类容器,Spring系列等个人总结。最后,希望各位在Java之路越走越远。Java之路道阻且长,最后一句话:Java之路为者长存,行者长至–送给你也送给我
—-Yang11😊
java快捷键(长期更新)
这里主要介绍我自己用的比较多的快捷键,利于开发
Alt + Enter 引入类,
Ctrl + O 查看我们继承的类或者接口中的方法,以及我们要实现的方法
Alt + Insert 打开可选择菜单
Ctrl+Alt+T 将代码包在一个块中
Ctrl+F 查找
.var 快速补齐
变量
变量的定义
变量:在程序运行过程中,其值可以发生改变的量。
从本质上讲,变量是内存中的一小块区域,其值可以在一定范围内变化。
变量的定义格式:
数据类型 变量名 = 初始化值; // 声明变量并赋值
int age = 18;
System.out.println(age);
或者
// 先声明,后赋值(使用前赋值即可)
数据类型 变量名;
变量名 = 初始化值;
double money;
money = 55.5;
System.out.println(money);
还可以在同一行定义多个同一种数据类型的变量,中间使用逗号隔开。但不建议使用这种方式,降低程序的可读性。
int a = 10, b = 20; // 定义int类型的变量a和b,中间使用逗号隔开
System.out.println(a);
System.out.println(b);
int c,d; // 声明int类型的变量c和d,中间使用逗号隔开
c = 30;
d = 40;
System.out.println(c);
System.out.println(d);
变量的使用:通过变量名访问即可。
使用变量时的注意事项
- 在同一对花括号中,变量名不能重复。
- 变量在使用之前,必须初始化(赋值)。
- 定义long类型的变量时,需要在整数的后面加L(大小写均可,建议大写)。因为整数默认是int类型,整数太大可能超出int范围。
- 定义float类型的变量时,需要在小数的后面加F(大小写均可,建议大写)。因为浮点数的默认类型是double, double的取值范围是大于float的,类型不兼容。
数据类型及数据处理
基本数据类型
基本数据类型 | 所占字节数 | 取值范围 | 备注 |
---|---|---|---|
byte | 1 | -128,127 | 默认字节 |
short | 2 | -32768,32767 | |
int | 4 | 约21亿 | 整数默认为int |
long | 8 | 不计 | 建议在数后加L |
boolen | 1 | 单精度,能精确到6~7位 | 布尔值判断真假 |
char | 2 | 字符表示Unicode表中的每一个符号 | UTF-8 |
float | 4 | 单精度,能精确到6~7位 | 有true和false |
double | 8 | 双精度,能精确到15~16位 | 小数默认为double |
引用数据类型
引用数据类型主要包括类,接口,数组,集合类数组,基本数据类型包装类
基本数据类型与引用数据类型对比
分类 | 基本数据类型 | 引用数据类型 |
---|---|---|
空间分配 | 在栈中进行分配 | 在堆中进行分配,读写速度比较慢 |
变量指向 | 变量名指向具体的数值 | 变量指向数据存储对象的地址 |
变量传递 | 变量之间的赋值是创建新的值拷贝 | 对象之间的赋值时传递引用地址 |
值比较 | ==&!= 是比较值 | =&!= 是比较地址 |
回收 | 创建销毁快 | 需要JVM进行回收 |
数据逻辑运算
运算符和表达式
运算符:对常量或者变量进行操作的符号
表达式:用运算符把常量或者变量连接起来符合java语法的式子就可以称为表达式,不同运算符连接的表达式体现的是不同类型的表达式。
+:是运算符,并且是算术运算符。
a + b:是表达式,由于+是算术运算符,所以这个表达式叫算术表达式。
算数运算符
符号 | 作用 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 取余 |
运算注意事项
A.char类型参与算术运算,使用的是计算机底层对应的十进制数值。需要我们记住三个字符对应的数值
B.算术表达式中包含不同的基本数据类型的值的时候,整个算术表达式的类型会自动进行提升。
提升规则:byte类型,short类型和char类型将被提升到int类型,不管是否有其他类型参与运算。
类型转换:
A.把小类型的变量赋值给大类型的变量,会自动转换
B.把大类型的变量赋值给小类型的变量或者引用数据类型需要转换(可能会抛出异常)需要进行强制转换
语法:在变量前添加要转换成的类型
赋值运算符
符号 | 作用 | 说明 |
---|---|---|
= | 赋值 | a=10,将10赋值给变量a |
+= | 加后赋值 | a+=b,将a+b的值给a |
-= | 减后赋值 | a-=b,将a-b的值给a |
*= | 乘后赋值 | a*=b,将a×b的值给a |
/= | 除后赋值 | a/=b,将a÷b的商给a |
%= | 取余后赋值 | a%=b,将a÷b的余数给a |
自增自减运算符
符号 | 作用 | 说明 |
---|---|---|
++ | 自增 | 变量的值加1 |
– | 自减 | 变量的值减1 |
注意事项:
++和-- 既可以放在变量的后边,也可以放在变量的前边。
单独使用时, ++和-- 无论是放在变量的前边还是后边,结果是一样的。
参与操作时,放在变量的后边,先拿变量参与操作,后拿变量做++或者–,放在变量的前边,先拿变量做++或者–,后拿变量参与操作。
关系运算符
符号 | 说明 |
---|---|
== | a==b,判断a和b的值是否相等,成立为true,不成立为false |
!= | a!=b,判断a和b的值是否不相等,成立为true,不成立为false |
> | a>b,判断a是否大于b,成立为true,不成立为false |
>= | a>=b,判断a是否大于等于b,成立为true,不成立为false |
< | a<b,判断a是否小于b,成立为true,不成立为false |
<= | a<=b,判断a是否小于等于b,成立为true,不成立为false |
逻辑运算符
符号 | 作用 | 说明 |
---|---|---|
& | 逻辑与 | a&b,a和b都是true,结果为true,否则为false |
| | 逻辑或 | a|b,a和b都是false,结果为false,否则为true |
^ | 逻辑异或 | a^b,a和b结果不同为true,相同为false |
! | 逻辑非 | !a,结果和a的结果正好相反 |
&& | 短路与 | 先判断前一个,前一个false则后一个不再判断 |
|| | 短路或 | 先判断前一个,前一个true则后一个不再判断 |
三元运算符
三元运算符语法格式:
关系表达式 ? 表达式1 : 表达式2;
解释:问号前面的位置是判断的条件,判断结果为boolean型,为true时调用表达式1,为false时调用表达式2。其逻辑为:如果条件表达式成立或者满足则执行表达式1,否则执行第二个,三元运算符可以进行嵌套。
程序控制
顺序结构
顺序结构是程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。
分支结构
if语句格式,if–else
格式:
if (关系表达式) {
语句体;
}
格式:
if (关系表达式) {
语句体1;
} else {
语句体2;
}
格式:
if (关系表达式1) {
语句体1;
} else if (关系表达式2) {
语句体2;
}
…
else {
语句体n+1;
}
执行流程:
计算关系表达式的值,关系表达式的值为true就执行语句体,false则执行下一个
switch语句结构
switch (表达式) {
case 1:
语句体1;
break;
case 2:
语句体2;
break;
...
default:
语句体n+1;
break;
}
执行流程:
- 首先计算出表达式的值
- 其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结 束。
- 最后,如果所有的case都和表达式的值不匹配,就会执行default语句体部分,然后程序结束掉。
循环结构
for (初始化语句;条件判断语句;条件控制语句) {
循环体语句;
}
/*初始化语句: 用于表示循环开启时的起始状态
条件判断语句:用于表示循环反复执行的条
循环体语句: 用于表示循环反复执行的内容,
条件控制语句:用于表示循环执行中每次变化的内容,简单说就是控制循环是否能执行下去*/
while循环
初始化语句;
while (条件判断语句) {
循环体语句;
条件控制语句;
}
do—while
初始化语句;
do {
循环体语句;
条件控制语句;
}while(条件判断语句);
三种循环的区别
-
三种循环的区别
- for循环和while循环先判断条件是否成立,然后决定是否执行循环体(先判断后执行)
- do…while循环先执行一次循环体,然后判断条件是否成立,是否继续执行循环体(先执行后判断)
-
for循环和while的区别
- 条件控制语句所控制的自增变量,因为归属for循环的语法结构中,在for循环结束后,就不能再次被访问到了
- 条件控制语句所控制的自增变量,对于while循环来说不归属其语法结构中,在while循环结束后,该变量还可以继续使用
-
死循环(无限循环)的三种格式
for(;😉{}, while(true){} , do {} while(true)
循环嵌套:多个循环嵌套在一起,默认执行方式是外循环执行一次,内循环执行一圈,即内循环是外循环的一个循环体
类
提示:这里默认认为接口是一种特殊的类
权限修饰符
权限修饰符 | 修饰对象 | 作用范围 | 备注 |
---|---|---|---|
private | 修饰数据成员,构造方法,方法成员 | 只能在备注的类中使用 | 不能修饰类(指外部类) |
default | 修饰类,数据成员,构造方法,方法成员 | 同包权限,同包内可见 | 默认权限(可缺省) |
protected | 修饰数据成员,构造方法,方法成员 | 同包或不同包下的子类 | 不能修饰类(指外部类) |
public | 修饰类,数据成员,构造方法,方法成员 | 可以在任何一个类中被调用 | 一个类中只能有一个修饰类的Public |
提示
1.并不是每个修饰符都可以修饰类(指外部类),只有public和default可以。
2.所有修饰符都可以修饰数据成员,方法成员,构造方法。
3.为了代码安全起见,修饰符不要尽量使用权限大的,而是适用即可。比如,数据成员,如果没有特殊需要,尽可能用private。
4.修饰符修饰的是“被访问”的权限。
变量分类
成员变量:包括静态成员变量和实例成员变量成员变量的作用域为整个类
静态成员变量 : 用static关键字修饰,一个类所拥有的变量,静态成员变量是指不管类创建了多少对象,系统仅在第一次调用类的时候为类变量分配内存,所有对象共享该类的类变量,因此可以通过类本身或者某个对象来访问类变量。
实例成员变量:和类变量对应,每个对象都拥有各自独立的实例变量,获取和使用实例成员变量时需要先创建对象。
局部变量:方法中声明的变量是局部变量,只在范围内有效,没有默认初始值,使用前必须赋值,当方法调用完,或者语句结束后,就自动释放。
**使用原则:**在使用变量时需要遵循的原则为:就近原则首先在局部范围找,有就使用;接着在成员位置找。
方法
静态类方法:使用static 关键字说明的方法
A. 系统只为该类创建一个版本,这个版本被该类和该类的所有实例共享。
B.类方法只能操作类变量,不能访问实例变量。类方法可以在类中被调用,不必创建实例来调用,当然也可以通过对象来调用。
实例方法:实例方法可以对当前对象的实例变量操作,而且可以访问静态成员变量。使用时需要创建对象。
抽象方法:用abstract修饰,提供继承重写的方法。
方法重载 要求:方法名相同,但是参数必须有区别。(参数不同可以使类型不同,顺序不同,个数不同)
方法的返回类型:若无返回类型,则声明为void.
方法中的变量作用域:
-
成员变量:整个类。
-
局部变量:定义起到方法块结束为止。
-
方法参数:整个方法或者构造方法。
-
异常处理参数:参数传递给异常处理方法
方法的修饰符
抽象方法: 用abstract 修饰,只有声明部分,方法体为空,具体在子类中完成。
类方法: 静态方法,用static 修饰,
-
调用时,使用类名作为前缀,而不是类的某个实例对象名
-
不能被单独对象拥有,属于整个类共享。
-
不能处理成员变量。
最终方法 :用final 修饰,不能被子类重新定义的方法。
本地方法 :用native 修饰的方法,表示用其他语言书写的特殊方法,包括C ,C++ ,FORTRAN ,汇编语言等
构造器
构造器作用:初始化对象,在对象创建时被调用
构造函数基本上定义了两个规则。分别如下:
- 构造函数名必须与其类名称相同
- 构造函数必须没有显式返回类型
无参构造函数(默认构造函数)默认构造函数的目的是根据类型为对象提供默认值,如:0,null等。
有参构造器:参数化构造函数用于为不同对象提供不同初始化的值。
代码块
普通代码块:在方法或语句中出现的{}就称为普通代码块。普通代码块和一般语句的执行顺序由他们在代码中出现的次序决定,先出现先执行。
静态代码块:在java中使用static关键字声明的代码块。静态块用于初始化类,为类的属性初始化。每个静态代码块只会执行一次。由于JVM在加载类时会执行静态代码块,所以静态代码块先于主方法执行。静态代码块不能存在于任何方法体内。静态代码块不能直接访问实例变量和实例方法,需要通过类的实例对象来访问。
构造代码块:直接在类中定义且没有加static关键字的代码块称为{}构造代码块。构造代码块在创建对象时被调用,每次创建对象都会被调用,并且构造代码块的执行次序优先于类构造函数。如果存在多个构造代码块,执行顺序由他们在代码中出现的次序决定,先出现先执行
**同步代码块:**使用synchronized(){}包裹起来的代码块,在多线程环境下,对共享数据的读写操作是需要互斥进行的,否则会导致数据的不一致性。同步代码块需要写在方法中
静态代码块与构造代码块区别与联系
相同点:都是JVM加载类后且在构造函数执行之前执行,在类中可定义多个,一般在代码块中对一些static变量进行赋值。
不同点:静态代码块在非静态代码块之前执行。静态代码块只在第一次new时执行一次,之后不在执行。而非静态代码块每new一次就执行一次
内部类
静态内部类:定义在类内部的静态类,就是静态内部类,静态内部类可以访问外部类所有的静态变量,而不可访问外部类的非静态变量;静态内部类的创建方式,new 外部类.静态内部类()
**成员内部类:**定义在类内部,成员位置上的非静态类,就是成员内部类,成员内部类可以访问外部类所有的变量和方法,包括静态和非静态,私有和公有。成员内部类依赖于外部类的实例,它的创建方式外部类实例.new 内部类()
**局部内部类:**定义在方法中的内部类,就是局部内部类,定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。局部内部类的创建方式,在对应方法内,new 内部类()
**匿名内部类:**匿名内部类就是没有名字的内部类(重要)
除了没有名字,匿名内部类还有以下特点:
-
匿名内部类必须继承一个抽象类或者实现一个接口。
-
匿名内部类不能定义任何静态成员和静态方法。
-
当所在的方法的形参需要被匿名内部类使用时,必须声明为 final。
-
匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
-
内部类的优点
我们为什么要使用内部类呢?因为它有以下优点:
- 一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!
- 内部类不为同一包的其他类所见,具有很好的封装性;
- 内部类有效实现了“多重继承”,优化 java 单继承的缺陷。
- 匿名内部类可以很方便的定义回调
特殊关键字
final:指最终,修饰方法时不能被重写,修饰变量时不能被修改(对于引用类型的变量指地址不可以被改变,内容的值拷贝后可以进行修改),且只能被赋值一次,修饰类不能被继承。
synchronize关键字:实现线程同步的锁,后在并发式编程中有仔细讲解
**this关键字:**this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针。
用法:
1.普通的直接引用,this相当于是指向当前对象本身。
2.形参与成员名字重名,用this来区分
3.引用本类的构造函数
**super关键字的用法:**super可以是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类。
用法:
1.普通的直接引用
与this类似,super相当于是指向当前对象的父类的引用,这样就可以用super.xxx来引用父类的成员。
2.子类中的成员变量或方法与父类中的成员变量或方法同名时,用super进行区分
3、引用父类构造函数
- super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句)
- this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)
break 跳出总上一层循环,不再执行循环(结束当前的循环体)
continue 跳出本次循环,继续执行下次循环(结束正在执行的循环 进入下一个循环条件)
return 程序返回,不再执行下面的代码(结束当前的方法 直接返回)
抽象类与接口
抽象类是用来捕捉子类通用特性的,是一种模板设计的思想用abstract修饰,接口是抽象方法的集合。
相同点
- 接口和抽象类都不能实例化
- 都位于继承的顶端,用于被其他实现或继承
- 都包含抽象方法,其子类都必须覆写这些抽象方法
参数 | 抽象类 | 接口 |
---|---|---|
声明 | 抽象类用abstract修饰 | 接口用interface修饰 |
实现 | 子类用extends来继承抽象类,子类不是抽象类需要实现抽象类中的所有方法 | 子类用implements关键字实现接口,需要提供接口类所有声明方法的实现 |
继承 | 单继承 | 多继承 |
构造器 | 抽象类可以有构造器 | 接口不能有构造器 |
访问修饰符 | 访问修饰符是任意的 | 默认是public,变量默认为static + final |
Java8中接口中引入默认方法和静态方法,以此来减少抽象类和接口之间的差异。
默认方法用default修饰,默认方法的调用会过继给实现类,
静态方法的调用可以直接用接口名调用
私有方法用来给本接口内的调用
枚举
用来做基本的信息分类,所有的枚举类都是Enum的子类,且枚举是一种多例模式,枚举类不可以被继承,构造器是私有的且不能创造对象,可以用来做分支结构的信息标志
Lambda表达式
适用范围:函数式接口
只包含一个抽象方法的接口,函数式接口上有@FunctionalInterface注解
lambda表达式基本形式
本质:作为接口的实例
(parameters) -> expression
或
(parameters) ->{ statements; }
- 左侧:指定了Lambda表达式需要的所有参数,形参列表,其实就是接口中的抽象方法的形参列表
- 右侧:制定了Lambda体,即Lambda表达式要执行的功能。即重写的抽象方法的方法体。
可简化形式:
/*
可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
*/
**作用域:**Lambda表达式对变量的访问限制和匿名内部类一样,因此Lambda表达式可以访问局部变量、局部引用,静态变量,实例变量。
方法引用与构造器引用
使用情景:当要传递给lambda体的操作已经有实现的方法了,就可以使用方法引用(同样效果的方法)本质上就是lambda表达式
**使用格式:**类(或对象)::方法名
1.对象::非静态方法–利用对象调用
@Test
public void test1(){
PrintStream out = System.out;
Consumer<String> consumer=out::println;
consumer.accept("hello");
}
2.类::静态方法
@Test
public void test2(){
Comparator<Integer> comparable=(x,y)->Integer.compare(x,y);
//使用方法引用实现相同效果
Comparator<Integer> integerComparable=Integer::compare;
System.out.println(integerComparable.compare(4,2));//结果:1
System.out.println(comparable.compare(4,2));//结果:1
}
3.类::非静态方法
@Test
public void test3(){
BiPredicate<String,String> bp=(x,y)->x.equals(y);
//使用方法引用实现相同效果
BiPredicate<String,String> bp2=String::equals;
System.out.println(bp.test("1","2"));//结果:false
System.out.println(bp.test("1","2"));//结果:false
}
正则表达式
用来做比较功能这里只做基本正则表达式的基本阐述,具体查看API文档,用的时候看就行了
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/regex/Pattern.html
主要利用String类中的matches方法
Java面向对象
面向对象原则
1.单一职责原则SRP(Single Responsibility Principle)类的功能要单一
2.开放封闭原则OCP(Open-Close Principle)
一个模块对于拓展是开放的,对于修改是封闭的
3.里式替换原则LSP(the Liskov Substitution Principle LSP)
子类可以替换父类出现在父类能够出现的任何地方
4.依赖倒置原则DIP(the Dependency Inversion Principle DIP)
高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。
5.接口分离原则ISP(the Interface Segregation Principle ISP)
设计时采用多个与特定客户类有关的接口比采用一个通用的接口要好。
继承
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码。
继承特点:
子类拥有父类非 private 的属性和方法。
子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
子类可以用自己的方式实现父类的方法。(以后介绍)。
封装
- 封装概述
是面向对象三大特征之一(封装,继承,多态)
是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界是无法直接操作的 - 封装原则
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问
成员变量private,提供对应的getXxx()/setXxx()方法 - 封装好处
通过方法来控制成员变量的操作,提高了代码的安全性
把代码用方法进行封装,提高了代码的复用性
多态
多态指父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。提高了程序的拓展性。
多态分为编译时多态和运行时多态。其中编辑时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的函数,通过编辑之后会变成两个不同的函数,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是我们所说的多态性。
实现多态的两种形式:
继承(多个子类对同一方法的重写)
接口(实现接口并覆盖接口中同一方法)。
方法重载(overload)实现的是编译时的多态性(也称为前绑定)
方法重写(override)实现的是运行时的多态性(也称为后绑定)。
一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。运行时的多态是面向对象最精髓的东西,要实现多态需要做两件事:
方法重写(子类继承父类并重写父类中已有的或抽象的方法);
对象造型(用父类型引用子类型对象,这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)。
多态的实现
Java实现多态有三个必要条件:继承、重写、向上转型。
继承:在多态中必须存在有继承关系的子类和父类。
重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。
只有满足了上述三个条件,我们才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而达到执行不同的行为。
对于Java而言,它多态的实现机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。
反射
**反射定义:**反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
获取反射的方式
public class Yang11 {
//获取反射机制三种方式
public static void main(String[] args) throws Exception {
//方式一(通过建立对象)
Student stu = new Student();
Class c1 = stu.getClass();
System.out.println(c1.getName());
//方式二(所在通过路径-相对路径)
Class c2 = Class.forName("pojo.Student");
System.out.println(c2.getName());
//方式三(通过类名)
Class c3 = Student.class;
System.out.println(c3.getName());
}
}
常用工具类API总结
JDK 中常用的包有哪些
java.lang:这个是系统的基础类;
java.io:这里面是所有输入输出有关的类,比如文件操作等;
java.nio:为了完善 io 包中的功能,提高 io 包中性能而写的一个新包;
java.net:这里面是与网络有关的类;
java.util:这个是系统辅助类,特别是集合类;
java.sql:这个是数据库操作的类。
String(操作字符串)
**String 底层原理:**String就是一个 char 类型的数组,只是使用的时候开发者不需要直接操作底层数组,用更加简便的方式即可完成对字符串的使用
String特性:
**不变性:**String 是只读字符串,对它进行任何操作,其实都是创建一个新的对象,再把引用指向该对象。不变模式的主要作用在于当一个对象需要被多线程共享并频繁访问时,可以保证数据的一致性。String不可变但不代表引用不可以变
**线程安全性:**String中的对象是不可变的,也就可以理解为常量,线程安全
**性能:**每次对String 类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String 对象。
常量池优化:String 对象创建之后,会在字符串常量池中进行缓存,如果下次创建同样的对象时,会直接返回缓存的引用。
不可继承:使用 final 来定义 String 类,表示 String 类不能被继承,提高了系统的安全性。
基本常用方法
indexOf():返回指定字符的索引。
charAt():返回指定索引处的字符。
replace():字符串替换。
trim():去除字符串两端空白。
split():分割字符串,返回一个分割后的字符串数组。
getBytes():返回字符串的 byte 类型数组。
length():返回字符串长度。
toLowerCase():将字符串转成小写字母。
toUpperCase():将字符串转成大写字符。
substring():截取字符串。—包前不包后
equals():字符串比较
API文档查看地址:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html
Object(祖宗类)
toString():默认返回堆内存的地址信息,方便子类重写可以获得内容、
equals(): 方便子类重写,更推荐使用Objects比较数据内容,字符串已经重写了equals
wait(): 线程等待方法,具体了解可见后并发编程章节
notify(): 线程唤醒方法,具体了解可见后并发编程章节
finalize(); 该方法一般由垃圾回收器来调用,当我们调用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,是判断一个对象是否可回收的方法。
StringBulider&&StringBuffer(操作字符串)
可变性:StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,char[] value,这两种对象都是可变的
**线程安全性:**StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder并没有对方法进行加同步锁,所以是非线程安全的
性能:StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StirngBuilder 相比使用StringBuffer 仅能获得10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
apend(): 连接字符串
capacity(): 判断容量
charAt(): 返回指定索引处的字符
delete(i…):删除此序列的子字符串中的字符。
insert(…): 将参数的字符串表示形式boolean
插入到此序列中
reverse():导致此字符序列被相反的序列替换
更多的使用可以查看API文档
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/StringBuilder.html
对于三者使用的总结
如果要操作少量的数据用 = String
单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
Date(日期类)
Date(long time): 把时间毫秒值转换为date日期
settime(long time): 设置当前毫秒值对应的时间 // 1、创建一个Date类的对象:代表系统此刻日期时间对象
Date d = new Date();
System.out.println(d);
// 2、获取时间毫秒值
long time = d.getTime();
System.out.println(time);
long time1 = System.currentTimeMillis();
System.out.println(time1);
System.out.println("----------------------------");
// 1、得到当前时间
Date d1 = new Date();
System.out.println(d1);
Date d3 = new Date();
d3.setTime(time1);//将时间毫秒值转化为日期格式
simpledateformat
构造器
simpledateformat() 创建默认对象,使用默认格式
simpledateformat(string pattern)创建对象,并使用指定的形式
方法
format(Date date)将日期格式转换成指定格式的日期对象
format(Obeject time)将时间毫秒值转换成指定格式的日期对象
Date d = new Date();
System.out.println(d);
// 2、格式化这个日期对象 (指定最终格式化的形式)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a");
// 3、开始格式化日期对象成为喜欢的字符串形式
String rs = sdf.format(d);
System.out.println(rs);
Arrays(操作集合容器)
sort():对数组内内容进行排序–可以自定义comparator接口自定义比较规则
arrayList.sort((Integer o1, Integer o2)-> o2-o1);
for (Integer integer : arrayList) {
System.out.print(integer+" ");
}
Arrays工具类具体请查阅API文档
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Arrays.html
File(操作IO流工具)
File 类定义了一些与平台无关的方法来操作文件,File类主要用来获取或处理与磁盘文件相关的信息,像文件名、 文件路径、访问权限和修改日期等,还可以浏览子目录层次结构,多用于操作文件。
Files. exists():检测文件路径是否存在。
Files. createFile():创建文件。
Files. createDirectory():创建文件夹。
Files. delete():删除一个文件或目录。
Files. copy():复制文件。
Files. move():移动文件。
Files. size():查看文件个数。
Files. read():读取文件。
Files. write():写入文件。
//这里进行一些简单的演示
File f = new File("file\\src\\data.txt");
// a.创建新文件,创建成功返回true ,反之 ,不需要这个,以后文件写出去的时候都会自动创建
System.out.println(f.createNewFile());
File f1 = new File("file\\src\\data02.txt");
System.out.println(f1.createNewFile()); // (几乎不用的,因为以后文件都是自动创建的!)
// b.mkdir创建一级目录
File f2 = new File("D:/resources/aaa");
System.out.println(f2.mkdir());
// c.mkdirs创建多级目录(重点)
File f3 = new File("D:/resources/ccc/ddd/eee/ffff");
// System.out.println(f3.mkdir());
System.out.println(f3.mkdirs()); // 支持多级创建
// d.删除文件或者空文件夹
System.out.println(f1.delete());
File f4 = new File("D:/resources/xueshan.jpeg");
System.out.println(f4.delete()); // 占用一样可以删除
// 只能删除空文件夹,不能删除非空文件夹.
File f5 = new File("D:/resources/aaa");
System.out.println(f5.delete());
}
结语
感谢在学习途中乐于分享的每一位码员,有了你们的分享才让学习者变得更轻松
本文部分总结借鉴于:https://blog.csdn.net/qq_41701956/article/details/110119625
作者:Yang11😊