Java 基础加强
01-面向对象进阶:static、继承、单例
static

static修饰成员变量


static修饰成员变量的应用场景
在开发中,如果某个数据只需要一份,且希望能够被共享(访问、修改),则该数据可以定义成类变量来记住。
1、成员变量有几种?各自在什么情况下定义?
类变量:数据只需要一份,且需要被共享时(访问,修改)
实例变量:每个对象都要有一份,数据各不同(如:name、score、age)
2、访问自己类中的类变量,是否可以省略类名不写?
可以的
注意:在某个类中访问其他类里的类变量,必须带类名访问
static修饰成员方法
有static修饰的成员方法,属于类
无static修饰的成员方法,属于对象。

static修饰成员方法的应用场景
类方法的常见应用场景
类方法最常见的应用场景是做工具类。
工具类是什么?
工具类中的方法都是一些类方法,每个方法都是用来完成一个功能的,工具类是给开发人员共同使用的。
为什么工具类中的方法要用类方法,而不用实例方法?
实例方法需要创建对象来调用,此时对象只是为了调用方法,对象占内存,这样会浪费内存。
类方法,直接用类名调用即可,调用方便,也能节省内存。
1.类方法有啥应用场景?
可以用来设计工具类。
2.工具类是什么,有什么好处?
工具类中的方法都是类方法,每个类方法都是用来完成一个功能的。
提高了代码的复用性;调用方便,提高了开发效率。
3.为什么工具类要用类方法,而不是用实例方法?
实例方法需要创建对象来调用,会浪费内存。
4.工具类定义时有什么要求?
工具类不需要创建对象, 建议将工具类的构造器私有化。
static的注意事项
类方法中可以直接访问类的成员,不可以直接访问实例成员。
实例方法中既可以直接访问类成员,也可以直接访问实例成员。
实例方法中可以出现this关键字,类方法中不可以出现this关键字的
static的应用知识:代码块
代码块是类的5大成分之一(成员变量、构造器、方法、代码块、内部类)。
代码块分为两种:
静态代码块:
格式:static { }
特点:类加载时自动执行,由于类只会加载一次,所以静态代码块也只会执行一次。
作用:完成类的初始化,例如:对类变量的初始化赋值。
实例代码块:
格式:{ }
特点:每次创建对象时,执行实例代码块,并在构造器前执行。
**作用:**和构造器一样,都是用来完成对象的初始化的,例如:对实例变量进行初始化赋值。
static的应用知识:单例设计模式
什么是设计模式(Design pattern)?
一个问题通常有n种解法,其中肯定有一种解法是最优的,这个最优的解法被人总结出来了,称之为设计模式。
设计模式有20多种,对应20多种软件开发中会遇到的问题。
单例设计模式:确保一个类只有一个对象。
写法
把类的构造器私有。
定义一个类变量记住类的一个对象。
定义一个类方法,返回对象。
1.什么是设计模式,设计模式主要学什么 ? 单例模式解决了什么问题 ?
设计模式就是具体问题的最优解决方案。
解决了什么问题? 怎么写?
确保一个类只有一个对象。
2.单例怎么写? 饿汉式单例的特点是什么?
把类的构造器私有;定义一个类变量存储类的一个对象;提供一个类方法返回对象。
在获取类的对象时,对象已经创建好了。
3.单例有啥应用场景,有啥好处?
任务管理器对象、获取运行时对象。
在这些业务场景下,使用单例模式,可以避免浪费内存。
懒汉式单例设计模式
拿对象时,才开始创建对象。
写法
把类的构造器私有。
定义一个类变量用于存储对象。
提供一个类方法,保证返回的是同一个对象。
继承
继承的快速入门


1、什么是继承 ? 继承后有啥特点 ?
继承就是用extends关键字,让一个类和另一个类建立起一种父子关系。
子类可以继承父类非私有的成员。
2、带继承关系的类,Java会怎么创建它的对象?对象创建出来后,可以直接访问哪些成员?
带继承关系的类,java会用类和其父类,这多张设计图来一起创建类的对象。
对象能直接访问什么成员,是由子父类这多张设计图共同决定的,这多张设计图对外暴露了什么成员,对象就可以访问什么成员。
继承相关的注意事项
①权限修饰符

| 修饰符 | 本类里 | 同一个包中的类 | 子孙类 | 任意类 |
|---|---|---|---|---|
| private | √ | |||
| 缺省 | √ | √ | ||
| protected | √ | √ | √ | |
| public | √ | √ | √ | √ |
②单继承、Object类
Java是单继承的,Java中的类不支持多继承,但是支持多层继承。
object类是java所有类的祖宗类。我们写的任何一个类,其实都是object的子类或子孙类。
③方法重写
什么是方法重写?
当子类觉得父类中的某个方法不好用,或者无法满足自己的需求时,子类可以重写一个方法名称、参数列表一样的方法,去覆盖父类的这个方法,这就是方法重写。
注意:重写后,方法的访问,Java会遵循就近原则 。
方法重写的其它注意事项
重写小技巧:使用Override注解,他可以指定java编译器,检查我们方法重写的格式是否正确,代码可读性也会更好。
子类重写父类方法时,访问权限必须大于或者等于父类该方法的权限(public>protected>缺省 )。
重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小。
私有方法、静态方法不能被重写,如果重写会报错的。
④子类中访问其他成员的特点
1、在子类方法中访问其他成员(成员变量、成员方法),是依照**就近原则的。
先子类局部范围找。
然后子类成员范围找。
然后父类成员范围找,如果父类范围还没有找到则报错。
2、如果子父类中,出现了重名的成员,会优先使用子类的,如果此时一定要在子类中使用父类的怎么办?
可以通过super关键字,指定访问父类的成员:super.父类成员变量/父类成员方法
⑤子类构造器的特点
子类构造器的特点:
子类的全部构造器,都会先调用父类的构造器,再执行自己。
子类构造器是如何实现调用父类构造器的:
默认情况下,子类全部构造器的第一行代码都是 super() (写不写都有) ,它会调用父类的无参数构造器。
如果父类没有无参数构造器,则我们必须在子类构造器的第一行手写super(….),指定去调用父类的有参数构造器。


1.子类构造器有啥特点?
子类中的全部构造器,都必须先调用父类的构造器,再执行自己。
2、super(…)调用父类有参数构造器的常见应用场景是什么?
为对象中包含父类这部分的成员变量进行赋值。
3、this(…)的作用是什么?
在构造器中调用本类的其他构造器。
4、this(…)和super(…)的使用需要注意什么?
都必须放在构造器的第一行。
⑥注意事项的小结
this和super详情
lthis:代表本类对象的引用;super:代表父类存储空间的标识。

为什么子类构造器一定要先调用父类的构造器:
引入继承后,子类对象是由子类和父类这多张设计图共同创建出来的,当创建子类对象,调用子类构造器为子类的成员变量初始化时,子类构造器肯定需要先调用父类构造器,把父类中的成员变量先进行初始化。
注意:super(…)必须放在构造器的第一行,否则报错
子类构造器调用父类构造器有啥应用场景?
为父类这部分成员变量进行初始化赋值。
02-面向对象进阶:多态、抽象类、接口
多态

对象多态:现实中的身份有可能有很多
行为多态:不同的人都会跑,但效果不一样(编译看左边,运行看右边)


1、使用多态有什么好处?存在什么问题?
可以解耦合,扩展性更强;使用父类类型的变量作为方法的形参时,可以接收一切子类对象。
多态下不能直接调用子类的独有方法。
2、类型转换有几种形式?能解决什么问题?
自动类型转换、强制类型转换。
可以把对象转换成其真正的类型,从而解决了多态下不能调用子类独有方法的问题。
3、强制类型转换需要注意什么?
存在继承/实现时,就可以进行强制类型转换,编译阶段不会报错。
但是,运行时,如果发现对象的真实类型与强转后的类型不同会报错(ClassCastException)。
4、强制类型转换前?Java建议我们做什么事情?
l使用instanceof判断当前对象的真实类型:对象 instanceof 类型 。
final
认识final

抽象u补充知识:常量详解类

抽象类
认识抽象类

抽象类的注意事项、特点
抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类。
类该有的成员(成员变量、方法、构造器)抽象类都可以有。
**抽象类最主要的特点:**抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现。
一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。

1、抽象类的应用场景和好处是什么?
两种主要的应用场景,一种是:用抽象类,我们可以把子类中相同的代码,包括方法签名都抽上来,这样能更好的支持多态,以提高代码的灵活性。
一种是:反过来用,我们不知道系统未来具体的业务实现时,我们可以先定义抽象类,将来让子类去继承实现,以方便系统的扩展。
抽象类的常见应用场景:模板方法设计模式

模板方法设计模式的写法
1、定义一个抽象类。
2、在里面定义2个方法
一个是模板方法:把相同代码放里面去。
一个是抽象方法:具体实现交给子类完成。
多学一招:建议使用fina关键字修饰模板方法,为什么?
模板方法是给对象直接使用的,不能被子类重写。
一旦子类重写了模板方法,模板方法就失效了。
1、模板方法设计模式解决了什么问题?
解决方法中存在重复代码的问题。
2、模板方法设计模式应该怎么写?
定义一个抽象类。
在里面定义2个方法,一个是模板方法:放相同的代码里,一个是抽象方法:具体实现交给子类完成。
3、模板方法建议使用什么关键字修饰?为什么
建议使用final关键字修饰模板方法。
接口
接口概述

1、接口是什么?
使用interface关键字定义的一种结构, JDK 8之前,接口中只能定义成员变量和成员方法。
2、接口怎么使用?需要注意什么?
接口 是被类 实现的。

实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则实现类需要定义成抽象类。
3、接口的好处是啥?
弥补了类单继承的不足,类可以同时实现多个接口。
让程序可以面向接口编程,这样既不用关心实现的细节,也可以灵活方便的切换各种实现。
接口的好处(重点)
弥补了类单继承的不足,一个类同时可以实现多个接口。
让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现。
1、使用接口有啥好处,第一个好处是什么?
可以解决类单继承的问题,通过接口,我们可以让一个类有一个亲爹的同时,还可以找多个干爹去扩展自己的功能。
2、为什么我们要通过接口,也就是去找干爹,来扩展自己的功能呢?
因为通过接口去找干爹,别人通过你implements的接口,就可以显性的知道你是谁,从而也就可以放心的把你当作谁来用了。
3、使用接口的第二个好处是什么?
一个类我们说可以实现多个接口,同样,一个接口也可以被多个类实现的。这样做的好处是我们的程序就可以面向接口编程了,这样我们程序员就可以很方便的灵活切换各种业务实现了。
接口的其他细节:JDK8开始,接口中新增的三种方法

1、JDK8开始,接口中新增了哪些方法?
默认方法:使用default修饰,使用实现类的对象调用。
静态方法:static修饰,必须用当前接口名调用
私有方法:private修饰,jdk9开始才有的,只能在接口内部被调用。
他们都会默认被public修饰。
2、JDK8开始,接口中为啥要新增这些方法?
增强了接口的能力,更便于项目的扩展和维护。
接口的其他细节:接口的多继承、使用接口的注意事项[了解]
接口其他注意事项(了解)
1、一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承。
2、一个类实现多个接口,如果多个接口中存在方法签名冲突,则此时不支持多实现。
3、一个类继承了父类,又同时实现了接口,父类中和接口中有同名的默认方法,实现类会优先用父类的。
4、一个类实现了多个接口,多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
03-面向对象进阶:泛型、匿名内部类、泛型、枚举
内部类
是类中的五大成分之一(成员变量、方法、构造器、内部类、代码块),如果一个类定义在另一个类的内部,这个类就是内部类。
场景:当一个类的内部,包含了一个完整的事物,且这个事物没有必要单独设计时,就可以把这个事物设计成内部类。
内部类概述、成员内部类[了解]

1、和前面学过的实例方法一样,成员内部类的实例方法中,同样可以直接访问外部类的实例成员、静态成员。
2、可以在成员内部类的实例方法中,拿到当前外部类对象,格式是:外部类名.this 。
静态内部类[了解]

1.什么是静态内部类?如何创建对象? 有啥特点?
有static修饰的内部类。
外部类名.内部类名 对象名 = new 外部类.内部类(…);
可以直接访问外部类的静态成员,不能直接访问外部类的实例成员。
局部内部类[了解]

匿名内部类[重点]

1、匿名内部类的书写格式是什么样的 ?


2、匿名内部类有啥特点 ?
匿名内部类本质就是一个子类,并会立即创建出一个子类对象
3、匿名内部类有啥作用、应用场景?
可以更方便的创建出一个子类对象。
匿名内部类通常作为一个参数传输给方法。
枚举



泛型
认识泛型

泛型类

泛型接口

通过具体的类进行实现,在类中限制泛型。
泛型方法、泛型通配符、上下限

泛型的注意事项:擦除问题、基本数据类型问题

java.lang包下的常用API
| Object | LocalTime | Set | FileOutputStream | Properties |
|---|---|---|---|---|
| objects | LocalDateTime | HashSet | Reader | Thread |
| Integer | Duration | LinkedHashSet | FileReader | Runnable |
| StringBuilder | Period | TreeSet | Writer | Callable |
| StringBuffer | ZoneId | Map | FileWriter | ExecutorService |
| Math | ZonedDateTime | HashMap | BufferdInputStream | ThreadPoo****lExecutor |
| System | Arrays | LinkedHashMap | BufferdOutputStream | Socket |
| Runtime | Comparable | TreeMap | BufferedReader | ServerSocket |
| BigDecimal | Comparator | Iterator | BufferedWriter | Class |
| Date | Collection | Stream | PrintStream | Method |
| SimpleDateFormat | List | InputStream | PrintWriter | Constructor |
| Calendar | ArrayList | FileInputStream | ObjectInputStream | Field |
| LocalDate | LinkedList | OutputStream | ObjectOutputStream | Proxy … |


指的是从1970年1月1日00:00:00走到此刻的总的毫秒数,应该是很大的。 1s = 1000ms。
为啥选择“1970年1月1日00:00:00” 作为时间的起点?
1969年8月,贝尔实验室的程序员肯汤普逊利用妻儿离开一个月的机会,开始着手创造一个全新的革命性的操作系统,他使用B编译语言在老旧的PDP-7机器上开发出了Unix的一个版本。随后,汤普逊和同事丹尼斯里奇改进了B语言,开发出了C语言,重写了UNIX。




BigDecimal只是解决问题的手段,而不是最后的结果。






















对对象数组排序











常见算法
排序算法





正则表达式




异常



自定义异常


异常的处理


06-集合(一)



1、单列集合的代表是谁?双列集合的代表是谁?各自元素的特点是啥?
Collection、Map
2、Collection集合有哪两大常用的集合体系,各自有啥特点?
List系列集合:添加的元素是有序、可重复、有索引。
Set系列集合:添加的元素是无序、不重复、无索引。
Collection的常用方法


.addAll 讲一个集合的数据,完全复制到另一个集合中。
Collection的遍历方式

1、如何获取集合的迭代器? 迭代器遍历集合的代码具体怎么写?
Iterator
2、通过迭代器获取集合的元素,如果取元素越界会出现什么异常?
会出现NoSuchElementException异常。




1、集合中存储的是元素的什么信息?
集合中存储的是元素对象的地址。
List集合
特点、特有方法


遍历方式
①for循环(因为List集合有索引)
②迭代器
③增强for循环
④Lambda表达式
ArrayList集合的底层原理





LinkedList集合的底层原理







LinkedList的应用场景之一:可以用来设计队列、栈
Set集合
特点

HashSet集合的底层原理










1.3 HashSet去重原理
前面我们学习了HashSet存储元素的原理,依赖于两个方法:一个是hashCode方法用来确定在底层数组中存储的位置,另一个是用equals方法判断新添加的元素是否和集合中已有的元素相同。
要想保证在HashSet集合中没有重复元素,我们需要重写元素类的hashCode和equals方法。比如以下面的Student类为例,假设把Student类的对象作为HashSet集合的元素,想要让学生的姓名和年龄相同,就认为元素重复。
LinkedHashSet集合的底层原理


1.LinkedHashSet集合的特点和原理是怎么样的?
有序、不重复、无索引
底层基于哈希表,使用链表记录添加顺序。
TreeSet集合






注意事项:集合的并发修改异常问题

07-集合(二)、Stream
Collection的其他相关知识
前置知识:可变参数


Collections


Map集合
概述



1.Map集合是什么?什么时候可以考虑使用Map集合?
Map集合是键值对集合l需要存储一一对应的数据时,就可以考虑使用Map集合来做
2.Map集合的实现类有哪些?各自的特点是?
HashMap: 元素按照键是无序,不重复,无索引,值不做要求。
LinkedHashMap: 元素按照键是有序,不重复,无索引,值不做要求。
TreeMap:元素按照建是排序,不重复,无索引的,值不做要求。
常用方法


遍历方式






HashMap



1、HashMap的特点和底层原理?
由键决定:无序、不重复、无索引。HashMap底层是哈希表结构的。
基于哈希表。增删改查的性能都较好。
2、HashMap如何实现键的唯一性的?
依赖hashCode方法和equals方法保证键的唯一。
如果键要存储的是自定义对象,需要重写hashCode和equals方法。
LinkedHashMap


TreeMap


1.TreeMap集合的特点、原理是怎么样的?
根据键可排序、不重复、无索引
底层基于红黑树实现排序,增删改查性能较好
2.TreeMap集合对自定义类型的对象排序,有几种方式指定排序规则?
2种。
类实现Comparable接口,重写比较规则。
集合自定义Comparator比较器对象,重写比较规则。
补充知识:集合的嵌套

Stream流







08-File、递归、字符集,IO流(一)

File是java.io.包下的类, File类的对象,用于代表当前操作系统的文件(可以是文件、或文件夹)。
用于读写数据的(可以读写文件,或网络中的数据…)
File
创建对象



常用方法1:判断文件类型、获取文件信息

常用方法2:创建文件、删除文件

1.创建多级目录使用哪个方法?
public boolean mkdirs()
2.删除文件需要注意什么?
可以删除文件、空文件夹。
默认不能删除非空文件夹。
常用方法3:遍历文件夹

1.如何遍历文件夹下的文件对象,使用哪个API,有什么特点?
public File[] listFiles()(常用)。
只能遍历当前文件夹对象下的一级文件对象。
前置知识:方法递归
认识递归的形式

应用、执行流程、算法思想

前置知识:字符集






IO流




IO流-字节流









释放资源的方式


09-java.io包下的常用API-io流2
IO流-字符流

文件字符输入流-读字符数据进来

文件字符输出流-写字符数据出去



IO流-缓冲流

字节缓冲流


字符缓冲流




原始流、缓冲流的性能分析[重点]
建议使用字节缓冲输入流、字节缓冲输出流,结合字节数组的方式,目前来看是性能最优的组合。
IO流-转换流
引出问题:不同编码读取时会乱码

字符输入转换流


字符输出转换流



IO流-打印流





IO流-数据流



IO流-序列化流




补充知识:IO框架



10-特殊文件(XML、Properties)、日志框架
特殊文件:Properties属性文件




特殊文件:XML文件











日志技术












11-多线程


多线程的创建
方式一:继承Thread类



方式二:实现Runnable接口


方式三:实现Callable接口




Thread的常用方法


线程安全
什么是线程安全问题



用程序模拟线程安全问题

线程同步
认识线程同步



方式一:同步代码块



方式二:同步方法



方式三:Lock锁

线程通信



线程池
认识线程池


如何创建线程池?




线程池处理Runnable任务



线程池处理Callable任务


Executors工具类实现线程池



其它细节知识:并发、并行





其它细节知识:线程的生命周期



如何同时运行并线程安全?
悲观锁:一上来就加锁,没有安全感。每次只能一个线程进入访问完毕后,再解锁。线程安全,性能较差!
乐观锁:一开始不上锁,认为是没有问题的,大家一起跑,等要出现线程安全问题的时候才开始控制。线程安全,性能较好。
12-网络编程


网络通信三要素
IP地址








端口号


协议



特点:面向连接、可靠通信。
TCP的最终目的:要保证在不可靠的信道上实现可靠的传输。
TCP主要有三个步骤实现可靠传输:三次握手建立连接,传输数据进行确认,四次挥手断开连接。






UDP通信-快速入门



TCP通信-快速入门





通信-多发多收


TCP通信-同时接收多个客户端


TCP通信-综合案例



13-junit、反射、注解、动态代理
单元测试
快速入门





Junit框架的常见注解


反射
认识反射



获取类




获取类的构造器




获取类的成员变量




获取类的成员方法




作用、应用场景



注解
概述、自定义注解






元注解



注解的解析



应用场景
动态代理






变量
一、局部变量
二、成员变量
1、静态变量
2、实例变量