总结
类型转换
- 自动类型转换(小类型转大类型)
子类赋值给父类,会触发自动类型转换- 强制类型转换(大类型转小类型)
父类赋值给子类,需要强制类型转换
Person p = new Student(); //自动类型转换
Student s = (Student)p; //强制类型转换
多态
什么是多态?
同类型的对象,表现出的不同形态
多态的表现形式
父类类型 对象名称 = 子类对象
多态的前提
- 有继承/实现关系
- 有父类引用指向子类对象
Fu f = new Zi(); - 有方法重写
多态的好处
- 使用父类型作为参数,可以接收所有子类对象
- 体现多态的扩展性与便利
- 多态调用成员的特点
变量调用: 编译看左边,运行也看左边方法调用: 编译看左边,运行看右边
多态的弊端是什么?
- 不能使用子类的特有功能
引用数据类型的类型转换,有几种方式?
- 自动类型转换、强制类型转换
强制类型转换能解决什么问题?
- 可以转换成真正的子类类型,从而调用子类独有功能
- 转换类型与真实对象类型不一致会报错
- 转换的时候用instanceof关键字进行判断
扩展(参考图2的demo):
1,instanceof区分不了父类Animal和子类Dog,都会走if(x instanceof Animal)
解决方案:先判断Dog再判断Animal
2,isAssignableFrom(父类.class)判断是否为父类
x.getClass().isAssignableFrom(Animal.class)
包
什么是包?
包就是文件夹。用来管理各种不同功能的Java类,方面后期代码维护。
包名的规则
公司域名反写 + 包的作用
需要全部用英文小写,见名知意。
例如:com.baidu.www.test
使用其他类的规则
- 使用同一个包中的类时,不需要导包
- 使用java.lang包中的类时,不需要导包
- 其他情况都需要导包
- 如果同时使用两个包中的同类名,需要用全类名
final修饰符的作用
- final修饰方法:
表明该方法是最终方法,不能被重写
- final修饰类:
表明该类是最终类,不能被继承
- final修饰变量:
表明该变量变成了常量,只能被赋值一次
枚举
常量
- 常量一般作为系统的配置信息,方便维护,提高可读性
- `常量命名规范:`
1,单个单词:全部大写
2,多个单词:全部大写,单词之间用下划线隔开
- `细节:`
1,final修饰的变量是基本类型:那么变量存储的数据值不能发生改变
2,final修饰的变量是引用类型:那么变量存储的地址值不能发行改变,对象内部的属性可以改变。
访问权限
权限修饰符分类
- 有4种作用范围由小到大
private < 空着不写(缺省/默认) < protected < public
局部代码块、构造代码块、静态代码块
- 构造代码块
1,写在成员位置的代码块
2,作用:可以把多个构造方法中重复的代码抽取出来
3,执行时机:我们在创建本来对象的时候会先执行构造代码块再执行构造方法
4,缺点:不够灵活,有些构造方法不想调用构造代码块,就控制不住了
5,替代方案:重复代码抽取成公共方法;或者,构造方法之间通过this()调用
- 静态代码块
1,格式:static{}
2,特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发、只执行一次
3,使用场景:在类加载的时候,做一些数据初始化的时候使用。
抽象方法&抽象类
抽象方法
将共性的行为(方法)抽取到父类之后,
由于每一个子类执行的内容不一样,
所以,在父类中不能确定具体的方法体,
该方法就可以定义为抽象方法。
定义格式:
public abstract 返回值类型 方法名(参数列表);
抽象类
- 要求子类一定要实现的父类方法,需要在父类中声明该方法为抽象方法
- 如果一个类中存在抽象方法,那么该类就必须声明为抽象类
定义格式:
public abstract class 类名{}
注意事项
- 抽象类不能实例化
- 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
- 抽象类可以有构造方法(给父类中的属性赋值)
- 抽象类的子类(推荐1)
1,要么重写抽象类中的所有抽象方法(子类不是抽象类时,可以实例化)
2,要么是抽象类(要是想实例化,还得有个类实现子类继承的所有抽象方法)
接口
1,接口就是一种规则,是对行为的抽象
2,接口用关键字interface来定义
public interface 接口名 {}
3,接口不能实例化
4,接口和类之间是实现关系,通过implements关键字表示
public class 类名 implements 接口名 {}
5,接口的子类(实现类)
- 要么重写接口中所有的抽象方法
- 要么是抽象类
抽象类和接口的区别
JDK8和JDK9新增方法
内部类
静态内部类
成员内部类
匿名内部类
常用API
Object的toString()什么作用?
Object的equals()方法,比较内容或地址是否相同
注意:
1,这里演示的是自定义实体类JavaBean时,比较实体类时的用法
2,例如LocalDate、LocalTime、LocalDateTime内部的equals()比较的就是日期是否相等
写法1(推荐):Objects.equals(a,b),优点是防止a或b为null
写法2:a.equals(b)的缺点是一旦a为null,会报错
情景一:equals()默认比较a和b地址是否相同
方式1:Objects.equals(a,b)
方式2:a==b
情景二:比较a和b内容是否相同
1,重写javabean中Object的equals()方法为比较内容是否相等
2,Objects.equals(a,b)比较内容是否相等
StringBuilder
最终StringBuilder对象还是要转换为String进行输出
Math
System
BigDecimal 浮点型计算用法
BigDecimal 有 8 种 RoundingMode(舍入模式)
SimpleDateFormat 日期格式化(JDK8之前API,不推荐)
Calendar 日历(JDK8之前API,不推荐)
JDK8+日期时间API
LocalDate 日期(JDK8+)
LocalTime 时间(JDK8+)
LocalDateTime 日期时间(JDK8+)
日期时间格式化(JDK8+)
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);//2023-03-12T17:44:14.369
System.out.println("-------------");
//指定日期格式
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss EEE a");
//时间和格式,谁调用format()方法都可以,结果一样
String formatDateTime = dtf.format(localDateTime);
String formatDateTime2 = localDateTime.format(dtf);
System.out.println(formatDateTime);//2023-03-12 17:44:14 星期日 下午
System.out.println(formatDateTime2);//2023-03-12 17:44:14 星期日 下午
日期计算API(JDK8+)
minusHours()、minusMinutes()、minusSeconds()、minusNanos()、
plusHours()、plusMinutes()、plusSeconds()、plusNanos()、
isBefore()、isAfter()
Instant 日期时间-时间戳(非纯数字)(JDK8+)
Period 一段时间(计算两个日期间隔-年月日)(JDK8+)
duration 持续时间(计算两个日期时间间隔-天时分秒)
ChronoUnit 计时单位
包装类
正则表达式
Arrays常用API
基础类型或引用类型的数组如果要打印数组内容而不是地址,需要使用Arrays.toString(数组)
选择排序法
理解二分搜索的原理并实现
Lambda表达式
Collection集合
Collection集合体系
- 有序:按照集合存储时的顺序,存储/输出
- 排序:按照某个规则进行排序,存储/输出
Collection常用API
Collection集合的遍历方式
- 迭代器
- 增强for循环
- forEach()
泛型
泛型类
泛型方法
泛型接口
泛型的通配符:?
Set集合
HashSet
TreeSet
可变参数
Map集合
Map集合的格式和特点
Map集合的常用API和3种遍历方式
Map中entrySet()方法使用
/**
获取到Map集合中所有的键值对对象的集合(Set集合)。
Entry是Map的静态内部类,创建Map对象的时候会同时创建一个Entry对象,用来记录键与值的映射关系。
使用场景:Map转为内部为键值对(对象)的集合Set,遍历集合从而实现遍历Map
*/
public Set<Map.Entry<K,V>> entrySet():
//demo
Set<Map.Entry> entrySet = demoMap.entrySet();
for (Map.Entry entry : entrySet) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
Lambda遍历Map
demoMap.forEach((key,value)->{
System.out.println(key);
System.out.println(value);
});
不可变集合(of()方法,JDK9之后才支持)
Stream流
map()加工方法
- map去空格、变小写、遍历
- 把集合中的字符串封装成对象返回
异常体系
编译时异常处理方式1---throws(不推荐)
编译时异常处理方式2--try...catch...
编译时异常处理方式3--前两者结合(推荐)
运行时异常处理方式(推荐)
自定义异常处理类
logback日志框架
日志级别
相对路径
- 获取当前模块的相对路径A(即在哪个文件夹A下):
System.getProperty("user.dir")
File
- 使用相对路径时,模块名前不要添加斜杠或反斜杠!
File对象和常见API
引入的模块,使用相对路径获取不到文件
解决方案:参考Java--1中的3.3(注意再次使用同名模块的坑)
删除非空文件夹
递归
递归检索文件
io流(输入输出流)
字符集
编码和解码的字符集要保持一致,否则会乱码
io流体系
FileInputStream(文件字节输入流,输入到程序中)
FileOutputStream(文件字节输出流,输出到一个新文件中)
如果输出的路径对应的文件夹或文件不存在,系统会自动创建
字节流文件拷贝(try-catch-finally)
FileReader(字符输入流)
FileWrite(字符输出流)
字符流文件拷贝
缓冲流
- 原始流: FileInputStream、FileOutputStream、FileReader、FileWrite
- 缓冲流的用法就是在原始流的基础上,封装为缓冲流进行输入和输出
字节缓冲流
字节缓冲流与原始流性能测试
字符缓冲流
缓冲字符流按行读取并排序(排序案例)
转换流
对象序列化(存储)、反序列化(读取)
打印流
Properties属性集
- 可以把对象中的键值对信息存储在一个xxx.properties文件中
- 通常把系统配置信息存储在xxx.properties文件中
commons-io.jar框架
- apache提供的IO操作类库
多线程(Thread)
Thread、Runnable
Callable&FutureTask
为了线程安全->线程同步
线程安全的起因是什么?
多个线程同时访问同一个共享资源且存在修改资源。
案例1
解决方式
- 加锁:让多个线程实现先后依次访问共享资源,这样就解决了安全问题。
Thread、Runnable、Callable解决方式一样,在子线程的run()或call()中调用的方法,可以使用同步代码块、同步方法、同步锁三种方式实现线程同步,解决线程安全问题。- 方式1:同步代码块
- 方式2:同步方法
- 方式3:同步锁
线程通信
线程池
方式一:使用系统类ThreadPoolExecutor创建线程池对象
Runnable线程任务放入线程池
备注:最多5个线程,3个核心线程,2个临时线程,等5个队列占满,才会创建2个临时线程,此demo已经输出了5个线程,代表5个队列已满在排队,排队的任务是未执行的,所以输出5个线程的信息后,第11个任务就触发了线程池的拒绝策略
Callable线程任务放入线程池
方式二:使用工具类Executors创建线程池对象
线程池扩展
Thread创建的线程怎么使用线程池?
- 线程池其实是一种管理线程的方式,它可以提高线程的重复利用率,减少频繁创建和销毁线程的开销,提高程序的性能和可维护性。
线程池并不关心线程的创建方式,只要包装成Runnable类型就可以提交给线程池。- 因此,Thread创建的线程同样可以通过实现Runnable接口并提交给线程池,而不影响线程池的正常使用。
线程池API方法submit()、execute()
定时器
线程的状态
网络编程
网络编程可以让程序与网络上的其他设备中的程序进行数据交互。
网络通讯的模式和三要素(IP、端口、协议)
InetAddress(IP对象)
端口号
唯一标识正在计算机设备上运行的进程(程序)
1, 一个设备中,能否出现2个应用程序的端口号一样,为什么?
不可以,如果一样会出现端口冲突错误。
通信协议
连接和通信数据的规则被称为网络通信协议
传输层:TCP、UDP
TCP三次握手建立连接、4次挥手断开连接
UDP通信
UDP的三种通信方式:单播、广播、组播
单播
- 一对一发送消息
- 多对多发送消息
广播
组播
TCP通信
- 一对一通信
- 多发和多收
多线程解决多端
线程池优化
即时通信
模拟BS系统
Junit单元测试
注意:
- 不能在含有构造函数的类中,使用单元测试
什么是单元测试
单元测试快速入门
反射
获取Class对象,等于获取了类全部的成分
获取Class对象
获取构造函数
- 获取构造器
- 构造器实例化对象
获取成员变量
成员变量的赋值和取值
获取方法
用反射存储任意对象到文件中
用反射给集合添加不同类型数据
注解
- 自定义注解 & 解析注解
动态代理
//使用Proxy类创建代理对象
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
参数一:类加载器,负责加载代理类到内存中使用。
参数二:获取被代理对象实现的全部接口。代理要为全部接口的全部方法进行代理
参数三:代理的核心处理逻辑
XML
什么是XML、新建XML
文档约束(DTD、schema)
- DTD
- schema
解析XML数据