JavaSE复习
- 1.Java入门
- 1.1 cmd常见命令
- 1.2 JDK下载和安装
- 1.3 JRE和JDK
- 2.基础语法
- 2.1 注释和关键字
- 2.2 常量
- 2.3 变量
- 2.4 数据类型
- 2.4.1 基本数据类型
- 2.4.2 引用数据类型
- 2.5 IDEA 的下载和安装
- 3. 运算符
- 3.1 算数运算符
- 3.2 数据类型转换
- 3.2.1 隐式转换
- 3.2.2 强制转换
- 3.3 自增自减运算符
- 3.4 赋值运算符
- 3.5 关系运算符
- 3.6 逻辑运算符
- 3.7 短路逻辑运算符
- 3.8 三元运算符
- 3.9 原码、反码、补码
- 4 判断和循环
- 4.1 判断
- 4.1.1 if 语句
- 4.1.2 switch 语句
- 4.2 循环
- 4.2.1 for 循环
- 4.2.2 while 循环
- 4.2.3 跳转控制语句
- 5 数组
- 5.1 数组的定义
- 5.2 数组的初始化
- 5.2.1 静态初始化
- 5.2.2 动态初始化
- 5.2.3 二者区别
- 5.3 数组的访问
- 5.4 数组的遍历
- 5.5 Java内存分配
- 6 方法
- 6.1 方法的定义和调用
- 6.2 方法的重载
- 6.3 方法的内存
- 7 面向对象
- 7.1 类和对象
- 7.1.1 类的定义
- 7.1.2 类的对象
- 7.1.3 注意事项
- 7.2 封装
- 7.2.1 private关键字
- 7.3 就近原则
- 7.3.1 成员变量和局部变量
- 7.3.2 就近原则
- 7.4 this关键字
- 7.5 构造方法
- 7.5.1 特点
- 7.5.2 注意事项
- 7.6 标准JavaBean
- 7.6.1 插件
- 8 static
- 8.1 静态变量
- 8.2 静态方法
- 8.3 测试类、JavaBean类、工具类
- 8.4 工具类
- 8.5 static的注意事项
- 9 继承
- 9.1 继承的特点
- 9.2 成员变量的访问特点
- 9.3 成员方法的访问特点 @Override重写
- 9.4 继承中的构造方法
- 9.4.1 父类构造方法的调用
- 9.5 this 和 super的使用
- 10 多态
- 10.1 多态特点
- 10.2 多态优势和弊端
- 11 包.final.权限修饰符.代码块
- 11.1 包
- 11.2 final
- 11.3 权限修饰符
- 11.4 代码块
- 12 抽象方法、接口、内部类
- 12.1 抽象方法
- 12.2 接口
- 12.2.1 接口中成员的特点
- 12.2.2 接口和类的关系
- 12.2.3 JDK8新特性
- 12.3 内部类
- 12.3.1 成员内部类
- 12.3.2 静态内部类
- 12.3.3 局部内部类
- 12.3.4 匿名内部类
- 13 字符串
- 13.1 概述
- 13.1.2 创建方式
- 13.2 常用方法
- 13.2.1 比较
- 13.2.2 截取
- 13.2.3 替换
- 13.3 StringBuilder
- 13.3.1 构造方法
- 13.3.2 常用方法
- 13.4 StringJoiner
- 13.4.1 构造方法
- 13.4.2 成员方法
- 13.5 常见面试题
- 13.6 字符串原理
- 14 常用API
- 14.1 Math
- 14.2 System
- 14.3 Runtime
- 14.4 Object
- 14.4.1 对象克隆
- 14.5 Objects
- 14.6 BigInteger
- 14.6.1 构造方法
- 14.6.2 方法
- 14.7 BigDecimal
- 14.7.1 使用
- 14.8 正则表达式Pattern
- 14.8.1 正则表达式在字符串方法中的使用
- 15 小tips
- 15.1 键盘录入
- 15.2 生成随机数
1.Java入门
1.1 cmd常见命令
1.盘符名称+冒号+回车: 切换到某盘
2.dir 查看当前路径下所有文件、文件夹及隐藏文件
3.cd 进入目录
4.cls 清屏
5.exit 退出命令提示符窗口
1.2 JDK下载和安装
1.下载
http://www.oracle.com->Products->Java->右上角Download Java->JDK17->Windows->x64 Installer
2.配置环境变量
1)我的电脑空白处右键->属性->高级系统设置->高级->环境变量
2)新建->
变量名:JAVAHOME
变量值:E:\Java\JDK(将BIN删掉)->确定
3)PATH->编辑->新建->%JAVAHOME%\bin->上移到最上面->确定
1.3 JRE和JDK
1.JDK(Java Development Kit): java开发工具包,jdk17.0.6版本,包含了JRE、编译器以及许多调试、分析等工具软件。它能够创建和编译Java程序 。
2.JVM(Java Virtual Machine): 即Java虚拟机,用来运行Java字节码文件,JVM是Java跨平台的关键。因为它屏蔽了不同操作系统之间的差异,可以让相同的Java程序在不同的操作系统上运行出相同的结果。
3.JRE(Java Runtime Environment): 即Java运行时环境,它是运行Java已编译程序所必需的软件环境,包含了JVM、Java标准类库。JRE提供给只想运行Java程序的用户使用,不能用于创建新的程序,即不能将Java源代码编译程字节码文件。
2.基础语法
2.1 注释和关键字
1.单行注释 //多行注释 /**/
2.关键字 被java赋予特定含义的英文单词,关键字全部小写
常用的代码编辑器,针对关键字有特殊颜色标记
2.2 常量
整数、小数、字符串、字符、布尔、空
2.3 变量
2.4 数据类型
2.4.1 基本数据类型
1.整数
byte:-128~127(需要记住取值范围)1 byte
short:-32768~32767 2 bytes
int:10位数(最常用)4 bytes
long:19位数 8 bytes 使用需要加L标识 long num = 12345678L;
2.浮点数
这里是引用
double(双精度) 8字节
float(单精度) 4字节 使用需要加入F标识 float num = 12.3F;
3.字符型
4.布尔型
5.取值范围大小关系:
double>float>long>int>short>byte
2.4.2 引用数据类型
2.5 IDEA 的下载和安装
IDEA
3. 运算符
3.1 算数运算符
加+减-乘*除/取模%
1.当 ‘+’ 操作中出现字符串时,这个 ‘+’ 是字符串连接符,而不是算术运算;
2.在 ‘+’ 操作中,如果出现了字符串,就是连接运算符,否则就说算术运算。当连续进行 ‘+’ 操作时,从左到右逐个执行。
3.2 数据类型转换
3.2.1 隐式转换
1.取值范围小的数据自动转换为取值大的数据
byte->short->int->long->float->double
2.规则
1)取值范围小的和取值范围大的进行计算,小的会先提升为大的,再进行运算
2)byte short char三种类型的数据在运算的时候,都会先提升为int,然后再进行运算
3.2.2 强制转换
大转小: 目标数据类型 变量名 = (目标数据类型) 被强转的数据;
3.3 自增自减运算符
++ –
3.4 赋值运算符
= += -= *= /= %=
3.5 关系运算符
== != > >= < <=
3.6 逻辑运算符
& | !
3.7 短路逻辑运算符
&& ||
3.8 三元运算符
关系表达式?表达式1:表达式2;
3.9 原码、反码、补码
原码: 十进制数据的二进制表现形式,最左边是符号位,0为正,1为负
利用原码对正数计算是不会有问题的
但如果是负数计算,结果就出错,实际的运算结果和预期的结果是相反的
反码: 正数的反码不变,负数的反码在原码的基础上,符号位不变,数值取反
负数运算的时候,如果结果不跨0,是没有任何问题的,但如果结果跨0,跟实际结果会有1的偏差
补码: 正数的补码不变,负数的补码在反码的基础上+1
另外补码还能多记录一个特殊的值-128,该数据在一个字节下,没有原码和反码
计算机中的存储和计算都是以补码的形式进行的
4 判断和循环
4.1 判断
4.1.1 if 语句
if(关系表达式){ 语句体; }
if(关系表达式){ 语句体1; }else{ 语句体2; }
if(关系表达式){ 语句体1; }else if{ 语句体2; }else{ 语句体3; }
4.1.2 switch 语句
switch(表达式){case 值1:语句体1;break;case 值2:语句体2;break;default:语句体n+1;break;}
格式说明:
1.表达式:(将要匹配的值)取值为byte.short.int.char.JDK 5以后可以是枚举,JDK7以后是String
2.case:后面跟的是和表达式进行比较的值(被匹配的值)
3.default:如果所有情况都不匹配时,就执行该处的内容,和If语句的else相似
4.case后面的值只能是字面量,不能是变量
5.case给出的值不允许重复
6.default的位置和省略
位置:default不一定写在最下面,可以写在任意位置,只不过习惯会写在最下面
省略:default可以省略,与发布会有问题,但不建议省略
7.case穿透(向下穿透)
语句体当中没有写break,程序会继续执行下一个case的语句体,一直到有break或大括号为止
4.2 循环
4.2.1 for 循环
for(初始化语句;条件判断语句;条件控制语句){ 循环体语句; }
4.2.2 while 循环
java 初始化语句; while(条件判断语句){ 循环体语句; 条件控制语句; }
for循环和while循环的对比
相同点:
运行规则都是一样的
不同点:
1.for循环中,控制循环的变量,因为归属for循环的语法结构中,在for循环结束后,就不能被访问了
2.while循环中,控制循环的变量,对于while循环来说不对数其语法结构中,在while循环结束后,该变量还可以继续使用
3.for循环;知道循环次数或者循环的范围
4.while循环:不知道循环的次数,只知道循环的结束条件
4.2.3 跳转控制语句
1.continue 跳过本次循环,继续执行下次循环
2.break 结束整个循环
5 数组
1.数组指的是一种容器,可以用来存储同种数据类型的多个值,需要结合隐式转换考虑
2.建议:容器的类型和存储类型保持一致
5.1 数组的定义
两种格式
1.格式1:数据类型[ ] 变量名,例如:int [ ] arr。定义了一个int类型的数组,数组名是arr。
2.格式2:数据类型 变量名[ ], 例如:int arr[ ]。定义了一个int类型的变量,变量名是arr数组。
5.2 数组的初始化
5.2.1 静态初始化
数据类型[] 数组名 = new 数据类型[] {元素1,元素2,元素3}
int[] array = new int[]{11,22,33};
数据类型[] 数组名 = {元素1,元素2,元素3}
int[] array = {11,22,33};
5.2.2 动态初始化
数据类型[] 数组名 = new数据类型[数组长度]
java int[] array = new int[3]
初始化默认值:
1.整数类型:int.short.byte.long初始化值为0
2.小数类型:float,double初始化值为0.0
3.字符类型:char,初始化值为’/u0000’->空格
4.布尔类型:boolean,初始化值为false
5.引用类型:初始化值为null
5.2.3 二者区别
1.动态初始化: 手动指定数组的长度,由系统给出默认初始化值
只明确元素个数,不明确具体数值,推荐使用动态初始化
2.静态初始化: 手动指定数组元素,系统会根据元素个数,计算出数组长度
需求中已明确了要操作的具体数据,直接静态初始化即可
5.3 数组的访问
数组名[索引];
索引
1.从0开始,逐个+1增长,连续不间断,索引也叫做下角标,角标
2.把数据存储到数组当中:数组名[索引] = 具体数据/变量;
5.4 数组的遍历
数组的长度:数组名.length
5.5 Java内存分配
这部分 需要重新看!!!
6 方法
6.1 方法的定义和调用
无参数格式
public stastic void 方法名(){…}
有参数格式
public static void 方法名(参数){… …}
public static void 方法名(参数1,参数2,…){… …}
带返回值格式
public static 返回值类型 方法名(参数){
方法体;
return 返回值;
}
注意事项
1.方法不调用就不执行
2.方法与方法之间是平级关系,不能相互嵌套定义
3.方法的编写顺序和执行顺序无关
4.方法的返回值类型为void,表示该方法没有返回值,没有返回值的方法可以省略return不写.如果要编写return,后面不能跟具体数据
5.return语句下面,不能编写代码,因为永远执行不到,属于无效代码
6.2 方法的重载
在同一个类中,定义了多个同名的方法,这些同名的方法具有相同的功能
每一个方法具有不同的参数类型或参数个数,这些同名的方法,就构成了重载关系
6.3 方法的内存
(1)按值传递:值传递是当方法被调用时把实际参数,传给形式参数。这个是只是一个数值的传递,把实际参数的数值拷贝给形式参数,如果这个是时候形参发生改变那么拷贝的值也会发生改变,但是实际参数不会改变。因此形参的改变不会影响实际参数的改变。
值传递的适用数据类型:
1.八大基本数据类型(byte,short,int,long,char,float,double,boolean)
2.String类型
(2)引用传递:当方法调用时,实际参数的引用(地址)会传给形式参数,通过这个引用找到变量(在这里是对象)的真正地址,然后对地址中的值修改,所以对引用的操作等于对其指定的对象进行操作。
适用范围: 除String以外的数据类型的对象
7 面向对象
7.1 类和对象
1.什么是对象: 万物皆对象,客观存在的事物皆为对象。
2.什么是对象的属性: 对象具有的各种特征,每个对象的每个属性都拥有特定的值。
3.什么是对象的行为: 对象能够执行的操作。
4.什么是类: 类是对现实生活中一类具有共同属性和行为的事物的抽象,确定对象将会拥有的属性和行为。类是JAVA程序的基本组成单位。
类的特点:
(1)类是对象的数据类型;
(2)类是具有相同属性和行为的一组对象的集合。
5.类和对象的关系:类是对象的抽象,对象是类的实体。
6.类的组成:属性和行为。
属性:在类中通过成员变量来体现(类中方法外的变量)
行为:在类中通过成员方法来体现(和前面的方法相比去掉static关键字即可)
7.1.1 类的定义
public class 类名{
1.成员变量//属性.只定义.不给值
2.成员方法//行为
3.构造器
4.代码块
5.内部类
}
7.1.2 类的对象
类名 对象名 = new 类名();
Phone p = new Phone();
对象的使用
1.访问属性:对象名.成员变量
2.访问行为:对象名.方法名(…)
7.1.3 注意事项
1.用来描述一类事物的类,专业叫javabean类.在javabean类中,是不写main方法的
2.编写main方法的类,叫做测试类.
我们可以在测试类中创建javabean类的对象进行赋值调用
3.类名首字母建议大写,需要见名知意,驼峰模式.
4.一个Java文件中可以定义多个class类,且只能一个类是public 修饰,并且public修饰的类型必须成为代码文件名
实际开发中,一个java文件建议定义一个class类
5.成员变量的完整定义格式是:修饰符 数据类型 变量名称 = 初始化值;一般无需指定初始化值,存在默认值.
7.2 封装
封装原则: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问成员变量private,提供对应的getXxx() / setXxx()方法。
7.2.1 private关键字
1.是一个权限修饰符
2.可以修饰成员(成员变量和成员方法)
3.被private修饰的成员只能在本类中才能访问
4.private修饰的成员变量如果需要被其他类使用,提供相应的操作
提供"setXxx(参数)"方法,用于给成员变量赋值,方法用public修饰
提供"getXxx()"方法,用于获取成员变量的值,方法用public修饰
7.3 就近原则
7.3.1 成员变量和局部变量
成员变量: 定义在类的里面,方法的外面
局部变量: 定义在类的里面,方法的里面
7.3.2 就近原则
7.4 this关键字
1.this关键字代表当前类对象的引用(地址)方法被哪个对象调用,this就代表哪个对象
2.this关键字调用本类成员变量
3.this.本类成员方法():没有前提条件,this可以省略
4.this关键字也可以用于在构造函数中调用其他构造函数,但是只能定义在构造函数的第一行,因为初始化动作要先执行
class Person
{private String name;private int age;Person(){name = "baby";age = 1;System.out.println("Person run");}Person(String name){//成员变量和局部变量重名,可以用关键字this区分this.name = name;}Person(String name,int age){//调用其他构造函数时,只能定义在构造函数的第一行,因为初始化动作要先执行this();this.name = name;this.age = age;}public void speak(){System.out.println(this.name+":"+this.age);}
}
class ThisDemo
{public static void main(String[] args) {Person p = new Person("小强",10);p.speak();}
}
7.5 构造方法
构造方法也叫构造器.构造函数
作用:在创建对象的时候给成员变量进行赋值.
java public class Student{ 修饰符 类名(参数){ 方法体; } }
7.5.1 特点
1.方法名与类名相同,大小写也要一致
2.没有返回值类型,连void都没有
3.没有具体的返回值(不能由return带回结果数据)
4.在创建对象的时候由虚拟机自动调用,不能手动调用构造方法
5.每创建一次对象,就会调用一次构造方法
6.如果没有写任何构造方法,虚拟机会构造一个空参的构造方法
7.5.2 注意事项
1.构造方法的定义
如果没有定义构造方法,系统将给出一个默认的无参数构造方法
如果定义了构造方法,系统将不再提供默认的构造方法
2.构造方法的重载
带参构造方法和无参数构造方法,两者方法名相同,但是参数不同,这叫做构造方法的重载
3.推荐的使用方式
无论是否使用,都手动书写无参数构造方法,和带全部参数的构造方法
7.6 标准JavaBean
1.类名需要见名知意
2.成员变量使用private修饰
3.提供至少两个构造方法:无参构造方法和带全部参数的构造方法
4.成员方法:提供每个成员变量对应的setXxx()/getXxx()如果还有其他行为,也需要写上
7.6.1 插件
1.t子->File->Settings->Plugins->Marketplace->ptg->ok
右键点击空白处ptg to javabean
2.alt+insert->Constructor生成构造方法
alt+insert->Getter and Setter生成方法
3.ctrl+d复制当前行到下一行
8 static
8.1 静态变量
被static修饰的成员变量,叫做静态变量
特点
1.静态变量被所有对象共享
2.不属于对象,属于类
3.随着类的加载而加载,优先于对象存在
调用方式
类名调用
8.2 静态方法
特点
1.多用在测试类和工具类中
2.javabean类中很少会用
8.3 测试类、JavaBean类、工具类
测试类用来检查其他类是否书写正确
javabean类: 用来描述一类事物的类
工具类: 帮助我们做一些事情,但是不描述任何事物的类
8.4 工具类
帮助我们做一些事情但不描述任何事物的类
1.类名见名知意
2.私有化构造方法
3.方法定义为静态
调用方式
类名调用
8.5 static的注意事项
1.静态方法只能访问静态变量和静态方法(因为没有对象来调用非静态的成员变量或方法)
2.非静态方法可以访问静态变量或者静态方法,也可以访问非静态的成员变量和非静态的成员方法
3.静态方法中没有this关键字
9 继承
java中提供一个关键字extends,用这个关键字,我们可以让一个类和另一个类建立起继承关系.
优势:
可以把多个子类中重复的代码抽取到父类中,提高代码的复用性
子类可以在父类的基础上,增加其他的功能,使子类更强大
使用场景:
当类和类之间,存在相同(共性)的内容,并满足子类是父类中的一种,就可以考虑使用继承,来优化代码
9.1 继承的特点
1.Java只支持单继承:一个子类只有一个父类,一个父类可以有多个子类
2.支持多层继承:子类A继承父类B,父类B可以继承父类C
3.每个类都直接或者间接的继承于Object类
4.在父类中方法的权限修饰符是private,子类无法访问该方法,子类只能访问父类中非私的
5.子类只能继承父类成员变量和非私有的成员方法
9.2 成员变量的访问特点
就近原则
先在局部位置找,在本类成员位置找,父类成员位置找,逐级往上
如果出现重名的成员变量,name从局部位置往上找,this.name从本类成员位置往上找,super.name从父类成员位置开始往上找
9.3 成员方法的访问特点 @Override重写
就近原则
方法的重写:
在继承体系中,子类出现了和父类一模一样的方法声明,我们就称子类这个方法是重写的方法
格式:
1.@Override是放在重写后的方法上,校验子类重写时语法是否正确
2.加上注释后如果有红色波浪线,表示语法错误
3.建议重写方法都加@Override注解,代码安全.优雅
注意事项:
1.重写方法的名称,形参列表必须与父类中的一致
2.子类重写父类方法时,访问权限子类必须大于等于父类
3.子类重写父类方法时,返回值类型子类必须小于等于父类
4.建议:重写的方法尽量和父类保持一致
5.只有被添加到虚方法表中方法才能被重写
9.4 继承中的构造方法
1.父类中的构造方法不会被子类继承,但可以通过super调用
2.子类中的所有构造方法会默认先访问父类中的无参构造,再执行自己
子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据.子类初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化.
9.4.1 父类构造方法的调用
子类构造方法的第一行语句默认都是:super(),不写也存在,且必须在第一行
如果想调用父类有参构造,必须手动写super进行调用
9.5 this 和 super的使用
this理解为一个变量,表示当前该方法调用者的地址值
super代表父类的存储空间
10 多态
什么是多态: 同类型的对象,表现出不同的形态
多态的表现形式: 父类类型 对象名称 = 子类对象;
多态的前提:
1.有继承关系
2.有父类引用子类对象
3.有方法的重写
10.1 多态特点
变量调用:编译看左边,运行也看左边
编译看左边:javac编译代码的时候会看左边的父类中有没有这个变量,如果有编译成功;如果没有编译失败
运行看左边:java运行代码的时候,实际获取的是左边父类中的成员变量的值
方法调用:编译看左边,运行看右边
编译看左边:javac编译代码的时候会看左边的父类中有没有这个方法,如果有编译成功;如果没有编译失败
运行看右边:java运行代码的时候,实际获取的是右边子类中的方法
10.2 多态优势和弊端
优势:
1.在多态形势下,右边对象可以实现解耦合,便于扩展和维护
Person p = new Student();
p.work();//业务逻辑发生改变时,后续代码无需修改
2.定义方法的时候,使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利
class Animal {void makeSound() {System.out.println("Animal makes a sound");}
}class Dog extends Animal {@Overridevoid makeSound() {System.out.println("Dog barks");}
}class Cat extends Animal {@Overridevoid makeSound() {System.out.println("Cat meows");}
}
现在,我们定义一个方法,它接受一个 Animal 类型的参数:
void playWithAnimal(Animal animal) {animal.makeSound();
}
解释:
父类参数:这个方法使用了 Animal 作为参数类型,也就是父类。
接收所有子类对象:因为 Dog 和 Cat 都是 Animal 的子类,我们可以传递 Dog 和 Cat 对象给这个方法。
public class Main {public static void main(String[] args) {Dog dog = new Dog();Cat cat = new Cat();playWithAnimal(dog); // 输出: Dog barksplayWithAnimal(cat); // 输出: Cat meows}
}
弊端
1.不能调用子类的特有方法
解决方案:将调用者父类变回子类类型即可
Person p = new Student();
Student s = (Student)p;//强制类型转换,不能转成其他类的类型,会报错ClassCastException
11 包.final.权限修饰符.代码块
11.1 包
包就是文件夹,用来管理各种不同功能的java类,方便后期代码维护
包名的规则:公司域名的反写+包的作用,需要全部英文小写,见名知意
要求
使用其他类的规则:
1.使用同一个包中的类,不需要导包
2.使用java.lang包中的类时,不需要导包
3.其他情况都需要导包
4.如果同时使用两个包中的同类名,需要用全类名
11.2 final
final修饰方法表明该方法是最终方法,不能被子类重写
final修饰类表明该类是最终类,不能被继承
final修饰变量叫做常量,只能被赋值一次
final修饰的变量是基本类型:那么变量存储的数据值不能发生改变
final修饰的变量是引用类型:那么变量存储的地址值不能发生改变,对象内部的属性值可以改变
常量的命名规范
单个单词:全部大写
多个单词:全部大写,单词之间用下划线隔开
11.3 权限修饰符
实际开发中一般只用private和public
成员变量私有+方法公开
11.4 代码块
1.局部代码块方法里面:提前结束变量的生命周期
public void exampleMethod() {System.out.println("Method start");{int temp = 10;System.out.println("Inside local block, temp = " + temp);} // temp 的作用域结束,变量被销毁// 这里不能再访问 temp 变量System.out.println("Method end");
}
2.构造代码块写在成员位置的代码块,可以把多个构造方法中重复的代码抽取出来.在执行时,我们在创建本类对象的时候会先执行构造代码块 再执行构造方法
public class Example {// 构造代码块{System.out.println("Common initialization code");}// 构造方法1public Example() {System.out.println("Constructor 1");}// 构造方法2public Example(String message) {System.out.println("Constructor 2: " + message);}public static void main(String[] args) {new Example();new Example("Hello");}
}
3.静态代码块
格式: static()
需要通过static关键字修饰,随着类的加载而加载,并且自动触发,只执行一次
使用场景在类加载的时候,做一些数据初始化的时候使用
public class Example {// 静态代码块static {System.out.println("Static block: Class-level initialization");}// 构造方法public Example() {System.out.println("Constructor");}public static void main(String[] args) {System.out.println("Main method start");new Example();new Example();}
}
12 抽象方法、接口、内部类
12.1 抽象方法
抽象方法: 将共性的行为(方法)抽取到父类之后,由于每一个子类执行的内容是不一样的.所以,在父类中不能确定具体的方法体,该方法就可以定义为抽象方法.
抽象类: 如果一个类中存在抽象方法,那么该类就必须声明为抽象类
定义:
1.抽象方法的定义格式
public abstract 返回值类型 方法名(参数列表);
2.抽象类定义格式
public abstract class 类名{}
注意事项:
1.抽象类不能实例化(不能创建对象)
2.抽象类不一定有抽象方法,但有抽象方法的类一定是抽象类
3.可以有构造方法
4.抽象类的子类:要么抽象类中的所有抽象方法,要么是抽象类
12.2 接口
定义和使用:
1.接口用关键字interface来定义
public interface 接口名{}
2.接口不能实例化
3.接口和类之间是实现关系,通过implements关键字表示
public class 类名 implements 接口名{}
4.接口的子类(实现类)要么重写接口中的所有抽象方法;要么是是抽象类
注意:
1.接口和类是实现关系,可以单实现,也可以多实现
public class 类名 implements 接口名1,接口名2{}
2.实现类还可以在继承一个类的同时实现多个接口
public class 类名 extends 父类 implements 接口名1,接口名2{}
package com.hh.interfacedemo1;
public class Dog extends Animal implements Swim{public Dog() {}public Dog(String name, int age) {super(name, age);}@Overridepublic void eat() {//抽象System.out.println("狗吃骨头");}@Overridepublic void swim() {//接口System.out.println("狗刨游泳");}
}
12.2.1 接口中成员的特点
1.成员变量只能是常量,默认修饰符:public static final
2.构造方法没有
3.成员方法只能是抽象方法,默认修饰符public abstract
12.2.2 接口和类的关系
1.类和类的关系
继承关系,只能单继承,不能多继承,但可以多层继承
2.类和接口的关系
实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口(如果多个接口有重名方法,只重写一个就相当于都重写了)
3.接口和接口的关系
继承关系,可以多继承也可以单继承(如果实现类实现了最下面的子接口,那么就需要重写所有的抽象方法
12.2.3 JDK8新特性
JDK7以前:接口只能定义抽象方法
JDK8的新特性:接口中可以定义有方法体的方法
JDK9的新特性:接口中可以定义私有方法
JDK8以后允许在接口中定义默认方法,需要使用关键字default修饰,作用:解决接口升级的问题
接口中默认方法的定义格式
public default 返回值类型 方法名(参数列表){}
接口中默认方法的注意事项
1.默认方法不是抽象方法,所以不强制被重写.但是如果被重写,重写的时候去掉default关键字
2.public可以省略,default不能省略
3.如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写
12.3 内部类
内部类访问外部类成员: 内部类可以直接访问外部类的所有成员,包括私有成员。这是因为内部类被视为外部类的一部分。
外部类访问内部类成员: 外部类访问内部类的成员时,必须通过创建内部类的对象来实现。这适用于所有访问修饰符的成员(包括私有成员),因为外部类和内部类在同一个类中定义,具有完全的访问权限。
12.3.1 成员内部类
public class OuterClass {private String outerField = "Outer field";// 成员内部类class MemberInnerClass {void display() {System.out.println("Accessing from MemberInnerClass: " + outerField);}}public static void main(String[] args) {OuterClass outer = new OuterClass();MemberInnerClass inner = outer.new MemberInnerClass();inner.display(); // 输出: Accessing from MemberInnerClass: Outer field}
}
12.3.2 静态内部类
public class OuterClass {private static String staticOuterField = "Static Outer field";private String outerField = "Outer field";// 静态内部类static class StaticInnerClass {void display() {System.out.println("Accessing from StaticInnerClass: " + staticOuterField);// 不能直接访问外部类的非静态成员// System.out.println(outerField); // 错误}}public static void main(String[] args) {StaticInnerClass inner = new StaticInnerClass();inner.display(); // 输出: Accessing from StaticInnerClass: Static Outer field}
}
12.3.3 局部内部类
public class OuterClass {void methodWithInnerClass() {// 局部内部类class LocalInnerClass {void display() {System.out.println("Inside LocalInnerClass");}}LocalInnerClass localInner = new LocalInnerClass();localInner.display(); // 输出: Inside LocalInnerClass}public static void main(String[] args) {OuterClass outer = new OuterClass();outer.methodWithInnerClass();}
}
12.3.4 匿名内部类
public class OuterClass {void methodWithAnonymousClass() {// 创建一个实现接口的匿名内部类Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("Running from Anonymous Inner Class");}};// 创建一个继承类的匿名内部类Thread thread = new Thread(runnable) {@Overridepublic void run() {System.out.println("Running from Anonymous Inner Class in Thread");}};thread.start(); // 输出: Running from Anonymous Inner Class in Thread}public static void main(String[] args) {OuterClass outer = new OuterClass();outer.methodWithAnonymousClass();}
}
13 字符串
13.1 概述
1.java.lang.String类代表字符串,java程序中所有字符串文字(例如"abc")都为此类的对象,java.lang包在使用时不需要导包.
2.java程序中的所有字符串文字,都被视为此类的对象
3.字符串的内容是不会发生改变的,它的对象在创建后不能被更改
13.1.2 创建方式
1.直接赋值 String name = “aa”;
2.new构造方法
package com.hh.Stringdemo;
public class StringDemo1 {public static void main(String[] args) {String s1 = "abc";//只有这种方法创造出的字符串存储在串池当中//节约内存System.out.println(s1);String s2 = new String();System.out.println("@" + s2 + "!");//""String s3 = new String("abc");System.out.println(s3);//修改字符串的内容,先将字符串变成字符数组,更改之后再拼接char[] chs = {'a','b','c','d'};String s4 = new String(chs);System.out.println(s4);//"abcd"//再网络当中传输的数据都是字节信息,将字节信息转换成字符串byte[] bytes = {97,98,99,100};String s5 = new String(bytes);System.out.println(s5);//"abcd"}
}
13.2 常用方法
13.2.1 比较
"=="号比的是什么:
1.基本数据类型:比较的是具体的数据值
2.引用数据类型:比较的是地址值
字符串的比较
boolean equals方法(要比较的字符串) 完全一样结果为true,否则为false
boolean equalsIgnoreCase方法(要比较的字符串) 忽略大小写比较
13.2.2 截取
String substring(int beginIndex,int endIndex) 截取(包头不包尾,包左不包右)只有返回值才是截取的小串
String subString(int beginIndex) 截取到末尾
13.2.3 替换
String replace(旧值,新值) 替换只有返回值才是替换之后的结果
13.3 StringBuilder
StringBuilder可以看成是一个容器,创建之后里面的内容是可变的
作用: 提高字符串的操作效率
13.3.1 构造方法
public StringBuiler() 创建一个空白可变的字符串对象,不含有任何内容
public StringBuiler(String str) 根据字符串内容,来创建可变字符串对象
13.3.2 常用方法
public StringBuilder append(任意类型) 添加数据(连接字符串),并返回对象本身
public StringBuilder reverse() 反转容器中的内容
public int length() 返回长度(字符的个数)
public String toString() 通过toString()就可以实现把StringBuilder转换为String
13.4 StringJoiner
StringJoiner跟StringBuilder一样,也可以看成是一个容器,创建之后里面的内容是可变的
作用: 提高字符串的操作效率,而且代码编写特别简洁
13.4.1 构造方法
public StringJoiner(间隔符号) 创建一个StringJoiner对象,指定拼接时的间隔符号
public StringJoiner(间隔符号,开始符号,结束符号) 创建StringJoiner对象,拼接时的间隔符号,开始符号,结束符号
13.4.2 成员方法
public StrinJoiner add(添加的内容) 添加数据,并返回对象的本身
public int length() 返回长度(所有字符个数)
public String toString() 返回一个字符串(该字符串就是拼接之后的结果)
13.5 常见面试题
13.6 字符串原理
1.字符串存储的内存原理
直接赋值会复用字符串常量池中的数据
new出来的不会复用,而是开辟一个新的空间
2.==号比较的到底是的什么
基本数据类型比较的是数据值
引用数据类型比较的是地址值
3.字符串拼接的底层原理
如果没有变量参与,都是字符串直接相加,编译之后就是拼接之后的结果,运行时会复用串池中的字符串
如果有变量参与,每一行拼接的代码,都会在内存中创建新的字符串,浪费内存
4.StringBuilder提高效率原理图
所有要拼接的内容都会往StringBuilder中放,不会创建很多无用的空间,节约内存
5.StringBuilder源码分析
默认创建一个长度为16的字节数组
添加内容小于16,直接存
添加内容大于16会扩容(原来 容量 *2+2) sb.capacity()
如果扩容之后还不够,以实际长度为准sb.length()
14 常用API
14.1 Math
1.是一个帮助我们进行数学计算的工具类
2.私有化构造方法,所有的方法都是静态的
调用方式:
Math.方法()
package com.hh.mathdemo1;
public class MathDemo1 {public static void main(String[] args) {System.out.println(Math.round(-12.34));//-12System.out.println(Math.round(-12.54));//-13System.out.println(Math.pow(4,0.5));//2System.out.println(Math.pow(4,-2));//0.25System.out.println(Math.sqrt(4));//2返回平方根System.out.println(Math.cbrt(8));//2返回立方根}
}
14.2 System
System也是一个工具类,提供了一些与系统相关的方法
数组拷贝
1.如果数据源数组和目的地数组都是基本数据类型,那么两者的类型必须保持一致,否则会报错
2.在拷贝的时候需要考虑数组的长度,如果超出范围也会报错
3.如果数据源数组和目的地数组都是引用数据类型,那么子类类型也可以赋值给父类类型
package com.hh.systemdemo;public class SystemDemo1 {public static void main(String[] args) {//System.exit(0);//当前虚拟机正常停止//System.exit(1);//当前虚拟机异常停止(非零参数)long l = System.currentTimeMillis();System.out.println(l);//从时间原点开始后的多少毫秒,时间源:1970年1月1日0:0:0int[] arr1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int[] arr2 = new int[10];System.arraycopy(arr1, 6, arr2, 2, 3);//数据源数组,起始索引,目的地数组,起始索引,拷贝个数 for (int i = 0; i < arr2.length; i++) {System.out.println(arr2[i]);}//0 0 7 8 9 0 0 0 0 0}
}
14.3 Runtime
Runtime表示当前虚拟机的运行环境
package com.hh.runtimedemo;
import java.io.IOException;
public class RuntimeDemo1 {public static void main(String[] args) throws IOException {Runtime r1 = Runtime.getRuntime();// Runtime.getRuntime().exit(0);System.out.println(Runtime.getRuntime().availableProcessors());//8System.out.println(Runtime.getRuntime().maxMemory()/1024/1024);//1796System.out.println(Runtime.getRuntime().totalMemory()/1024/1024);//123System.out.println(Runtime.getRuntime().freeMemory()/1024/1024);//119Runtime.getRuntime().exec("notepad");}
}
14.4 Object
1.Object是Java中的顶级父类.所有的类都直接或间接的继承于Object类
2.Object类中的方法可以被所有子类访问,所以我们要学习Object类和其中的方法
1.当我们打印一个对象的时候,底层会调用对象的toString方法,把对象变成字符串,然后再打印在控制台上,打印完毕会换行处理.
toString方法的结论: 如果我们打印一个对象,想要看到属性值的话,那么就重写toString方法就可以了.在重写的方法中,把对象的属性值拼接.
2.如果没有重写equals方法,那么默认使用Object中的方法进行比较,比较的是地址值是否相等(对象)
3.一般来讲地址值对于我们意义不大,所以我们会重写,重写之后比较的就是对象内部的属性值了.
14.4.1 对象克隆
对象克隆: 把A对象的属性值完全拷贝给B对象,也叫对象拷贝,对象复制
14.5 Objects
Objects是一个工具类,提供了一些方法去完成一些功能
Object.equals(Object obj): 比较的是对象的引用是否相同,即判断两个对象是否是同一个实例。通常需要在具体的类中重写该方法,实现自定义的相等性比较逻辑。
Objects.equals(Object a, Object b): 经常用于比较两个对象是否相等,它会避免 null 引用导致的异常,同时也适用于比较任何两个对象,不限于特定类的实例。
14.6 BigInteger
14.6.1 构造方法
public class BigIntegerDemo1 {public static void main(String[] args) {//获取一个随机的大整数BigInteger big = new BigInteger(4,new Random());System.out.println(big);//获取一个指定的大整数BigInteger bd2 = new BigInteger("1");//字符串中必须是整数,否则会报错System.out.println(bd2);//获取指定进制的大整数//字符串中的数字必须是整数且必须和进制吻合BigInteger bd3 = new BigInteger("100",2);//4这里100表示的是后面的进制,输出会将进制转化为10后System.out.println(bd3);//静态方法获取BigInteger的对象内部有优化.//1.能表示范围比较小,在long的取值范围内,如果超出long的范围就不行了//2.在内部对常用的数字,-16~16进行了优化//3.对象一旦创建内部的数据不能发生改变BigInteger bd4 = BigInteger.valueOf(100);System.out.println(bd4);System.out.println(bd4);}
}
14.6.2 方法
14.7 BigDecimal
用于小数的精确计算
public class BigDecimalDemo1 {public static void main(String[] args) {//这种方式有可能是不精确的BigDecimal bd1 = new BigDecimal(0.01);BigDecimal bd2 = new BigDecimal(0.09);System.out.println(bd1);//0.01000000000000000020816681711721685132943093776702880859375System.out.println(bd2);//0.0899999999999999966693309261245303787291049957275390625BigDecimal bd3 = new BigDecimal("0.01");BigDecimal bd4 = new BigDecimal("0.09");BigDecimal bd5 = bd3.add(bd4);System.out.println(bd5);//0.10System.out.println(bd3);//0.01System.out.println(bd4);//0.09//如果表示的数字不大,没有超出double的取值范围,建议使用静态方法//如果要表示的数字比较大,超出了double的取值范围,建议使用构造方法//如果传递的是0~10之间的整数,包含0,包含10,那么方法会返回已经创建好的对象,不会重新newBigDecimal bd6 = BigDecimal.valueOf(10);System.out.println(bd6);}
}
14.7.1 使用
14.8 正则表达式Pattern
作用
1.校验字符串是否满足规则
2.在一段文本中查找满足要求的内容
14.8.1 正则表达式在字符串方法中的使用
15 小tips
15.1 键盘录入
1.导包
2.创建对象
3.接受数据
import java.util.Scanner;
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
遇到空格.制表符.回车就停止接收,这些符号后面的数据就不会接收了.会给后面的接收
nextInt();接收整数
nextDouble();接收小数
next();接收字符串
15.2 生成随机数
1.导包
2.创建对象
3.生成随机数
import java.util.Random
Random r = new Random();
int number = r.nextInt(随机数取值范围); //生成随机数的范围是从0-这个数值减1(包头不包尾,包左不包右)