javase知识图谱
2021-10-21 15:04:43 0 举报
AI智能生成
登录查看完整内容
javase知识图谱
作者其他创作
大纲/内容
jdk
jre
jvm
关键名词
jdk7或者jdk8
java历史
helloworld
给类、变量、方法等起的名称
首字母可以是字母、下划线、美元符号,但是不能是数字
其他部分只能是字母、下划线、数字、美元符号
java严格区分大小写
java驼峰标示和见名知意
规则
标识符
留给系统使用的关键字
保留字(关键字)
算术运算符
比较运算符
赋值运算符
逻辑运算符
三目运算符
位运算符
注意:各个运算符的优先级
运算符
byte
short
int
long
整型
float
double
浮点型
char
字符型
只占1位
true或者false
布尔型
基本数据类型
String
数组
对象
接口
引用数据类型
数据类型
java基础语法知识
代码从上向下依次执行
顺序结构
if
if...else
if..else if ...else
switch
分支结构
do ..while
while
for
增强for循环
循环结构
跳出当前循环
break
跳出本次循环
continue
1、返回结果值
2、如果后面没有参数,返回值,则表示结束程序
return
流程控制的语法规则
流程控制语句
面向过程编程
面向对象编程
面向接口编程
面向切面编程
函数式编程思想
编程思想
类是对象的抽象,对象是类的实例化
如何创建对应的对象
定义好一个类之后,会有默认的无参构造方法,如果自己添加了构造方法,则无参构造方法失效
注意:每次写具体的类的时候,一定要写上无参构造方法
构造器
指代当前对象
可以在构造方法中使用,区分参数和成员属性
在普通方法中使用,表示调用当前的属性或者当前类的方法,可以省略
用途
this
表示静态
可以定义在属性上,被所有的对象共享
可以定义在方法上,可以通过类名直接调用
可以定义在类上,但是是内部类
static
表示最终的
定义在类上,表示类不可以被继承
定义在方法上,表示方法不能被重写
定义在属性上,表示值不可以被修改
final
打包:区分同名的文件,分布在不同的目录
将不同的功能代码整合到一起
使用类中的某些方法的时候不在需要写类名,直接调用方法即可
静态导包
package
导包
或者第三方的组件
方便引用其他包的java类
import
规定方法、类等的访问范围
只能在本类中使用
private
只能在本类和本包中使用
default
只能在本类、本包、继承的子类中使用、
protected
任意地方都可以被访问
public
分类
访问修饰符
在同一个类中,定义了多个同名的方法
参数列表的个数不同
参数列表的类型不同
参数列表的顺序不同
重载有三种展示形式
方法的重载
类和对象
在代码中可以将某个代码块变成方法,抽象出某些工具类
广义的封装
1、将属性设置成私有,不能被外部直接访问
2、提供共有的set和get方法,使外部可以进行调用
3、可以实现更加复杂细致的内部逻辑判断
总结:保护类的内部实现细节,只提供公共的对外访问接口,保护类的安全
特点
狭义的封装
封装
子类可以拥有父类的某些属性和方法,但是私有的除外
java中式严格意义上的单继承
使用extends关键字来实现继承
解释说明
当父类中的某些方法不能满足子类的需要的时候,子类可以重写父类的方法,要求跟父类的方法名称一致
子类方法的访问修饰符>父类的访问修饰符
建议添加@override注解,在编译时提示错误
重写
表示的是父类的对象
在创建对象的时候,可以在子类中直接通过super关键字调用父类的构造方法
在子类方法中可以使用super.的方法调用父类的方法和属性
super
继承
通俗解释;对于同一个指令,不同的对象给予的不同反应
1、必须有继承关系
2、子类必须重写父类方法
3、父类引用指向子类对象
前提
由子类到父类,自动转换
由父类到子类,强制转换,一般通过instanceof进行判断
父类和子类对象的转换
多态
接口代表一种能力
接口代表一种规范
接口可以在一定程度上实现java的多继承
接口中的方法都是public abstract这样的访问修饰符,不能包含具体的方法实现
子类如果实现了某个接口,那么接口中的所有方法都要被重写,且实现具体的逻辑,如果没有实现的话,那么子类要么是子接口要么是抽象类
接口中的属性都是常量值
抽象类跟接口类似,可以定义抽象方法,也可以包含具体的实现
抽象类和抽象方法需要使用abstract关键字来进行修饰
抽象类的子类必须重写抽象类中的抽象方法,如果不重写的话,那么该子类也会成为一个抽象类
抽象类
一个JAVA文件中可以包含多个class,但是只能有一个public class,且多个class经过编译之后会自动生成对应的多个class字节码文件。
一个JAVA文件中的内部类,编译之后,内部类不会生成一个新的class字节码文件,由此可以将内部类看成是外部类的一个成员属性或成员对象,只是用class修饰而已。
拓展
如果一个类定义在另一个类的内部,此时称之为内部类
定义
例如:outClass外部类,innerClass内部类outClass.innerClass inner = new outClass().new innerClass();
创建内部类的时候,跟之前的方法不一样,需要在内部类的前面添加外部类来进行修饰
使用
内部类可以方便的访问外部类的私有属性,外部类不能访问内部类的私有属性,但是如果创建了内部类对象,此时可以在外部类中私有属性
内部类中不能定义静态属性
当内部类和外部类中具有相同的私有属性的时候,在内部类中访问的时候,可以直接访问内部类的属性,如果需要访问外部类的属性,那么需要添加 外部类名.this.属性名称
内部类可以嵌套内部类
使用场景
当定义了一个类,实现了某个接口的时候,在使用过程中只需要使用一次,没有其他用途,其实考虑到代码编写的简洁,可以考虑不创建具体的类,而采用new interface(){添加未实现的方法} 这种匿名内部类实现
看起来像是new了一个接口,实际上是new了一个接口的实现类,只是该类没有名字
匿名内部类
在内部类中可以定义静态内部类,使用static关键字进行修饰
外部类类名.内部类 内部类对象名 = new 外部类类名.内部类类名();
实例化规则
静态内部类
用到很少,了解即可
将内部类定义在外部类的方法中
方法内部类不能在外部类的方法以外的地方使用,所以方法内部类不能使用访问控制符和static修饰
使用规则
方法内部类
成员内部类
内部类
oop-面向对象
表示程序在运行过程中出现的非正常情况,编写代码的过程中尽可能少的减少异常出现的情况
代码级别无法解决的异常情况
Error
在程序运行过程中,由于输入的参数值的不同,可能会发生也可能不会发生
运行时异常
编译时异常,在ide中会显示的检查出来
checked异常
Exception
Throwable
try...catch...
try...catch...finally
在进行异常捕获的时候,return语句的不同位置会造成结果的不同
捕获异常
将异常情况抛出给调用者
注意,如果整个程序的运行过程中都没有异常的处理的话,最终异常会抛给jvm,不太友好,一般都要对异常进行处理
throws
抛出异常
异常的处理
java中提供了非常多的异常类,但是在某些项目中需要自己定义独特的异常处理方式,此时需要自定义异常
1、继承Exception
2、编写构造方法,可以传入自己想打印的异常信息
3、调用的时候通过throw向外抛出异常
步骤
自定义异常
异常
表示的是一些在程序编写过程中经常用到的类,可以进行提取,变成工具类
Integer
Byte
...
...\t
基本数据类型都由对应的包装类
自动拆箱和自动装箱
包装类
不可变字符串
StringBuffer
StringBuilder
可变字符串
使用比较少,一般用于获取当前时间及当前时间的毫秒值
Date
非常好用
返回格林威治时间
日历类
Calendar
数学类
Math
枚举类也是一个类,可以定义属性和方法,甚至可以写构造方法,填写具体的枚举类对象的时候,可以带参数,但是要跟构造方法进行匹配
enum
枚举类
对当前文件系统进行操作的类
File
常用类
连续的数组
链表结构
一组相同类型的数据的集合,可以使用不同的数据结构来存储数据
数据的类型必须是一致的
数组必须在声明的时候显示的给出长度
数组在插入和删除的时候,频繁的移动元素,效率比较低
数组在查找元素的时候可以按照下标查找
注意:排序方法问的相当多
ArrayList
Vector
LinkedList
List:有序不唯一
HashSet
TreeSet
SortedSet
EnumSet
CopyOnWriteArraySet
ConcurrentSkipListSet
Set:无序唯一
ArrayDeque
LinkedBlockingDeque
BlockingDeque
Deque
ArrayBlockingQueue
LinkedBlockingQueue
DelayQueue
PriorityBlockingQueue
SynchronousQueue
BlockingQueue
1. 队列中锁的实现不同 ArrayBlockingQueue实现的队列中的锁是没有分离的,即生产和消费用的是同一个锁; LinkedBlockingQueue实现的队列中的锁是分离的,即生产用的是putLock,消费是takeLock
2. 队列大小初始化方式不同 ArrayBlockingQueue实现的队列中必须指定队列的大小; LinkedBlockingQueue实现的队列中可以不指定队列的大小,但是默认是Integer.MAX_VALUE
区别
LinkedTransferQueue
TransferQueue
PriorityQueue
ConcurrentLinkedQueue
queue
Collection
扩展知识:ConcurrentHashmap
HashMap
hashtable
TreeMap
Map:键值对的数据
结合框架中可以使用不同类型的数据进行存储,但是某些方法无法使用,因此提出泛型的概念,来强制约束对应的结合处理类,保证处理的集合都是同一个数据类型
泛型类
泛型接口
泛型方法
泛型的上限
泛型的下限
高阶应用
泛型
集合
处理数据的读取和写出,不止是文件,还包含网络数据的处理
字节流
字符流
按照字节字符分
输入流
输出流
按照输入输出分
节点流
处理流
按照流是否嵌套
InputStream
OutputStream
FileInputStream
FileOutputStream
Reader
Writer
FileReader
FileWriter
BufferedInputstream
BufferedOutputStream
BufferedReader
BufferedWriter
ByteArrayInputStream
ByteArrayOutputStream
InputStreamReader
OutputStreamWriter
DataInputStream
DataOutputStream
ObjectInputStream
ObjectOutputStream
PrintStream
System.in
System.out
详细子类
1、创建流之后相当于源数据和目的数据上建议连接,需要占用一定的系统资源
2、每次使用完流之后一定要进行关闭操作
3、字节流是万能的,可以输入输出任意类型的数据
4、在处理纯文本文件的时候可以使用字符流
注意事项
io
核心概念
一个进程中至少有一个线程
JAVA与javac
线程与进程的区别
区别举例
【1】继承Thread类【2】重写run方法【3】创建对象, 调用start()方法, 启动线程
操作步骤
不要直接调用run方法,而需要使用Thread类的start方法才能够启动线程,直接调用run相当于就是一次普通的方法调用
线程的执行
▪ 在Java中负责线程的这个功能的是Java.lang.Thread 这个类▪ 可以通过创建 Thread 的实例来创建新的线程。▪ 每个线程都是通过某个特定Thread对象所对应的方法run( )来完成其操作的,方法run( )称为线程体。▪ 通过调用Thead类的start()方法来启动一个线程。
继承Thread类
【1】实现Runnable接口【2】重写run方法【3】创建Thread对象,将刚刚创建好的runnable的子类实例作为thread的构造参数【4】调用thread.start()方法, 启动线程
该实现方式使用了代理设计模式
实现Runnable接口
继承Thread类方式的缺点:那就是如果我们的类已经从一个类继承(如小程序必须继承自 Applet 类),则无法再继承 Thread类
▪ 通过Runnable接口实现多线程▪ 优点:可以同时实现继承。实现Runnable接口方式要通用一些。▪ 1)避免单继承▪ 2)方便共享资源 同一份资源 多个代理访问
两种创建方式的区别
线程的创建方式
– 用new关键字建立一个线程后,该线程对象就处亍新生状态。– 处于新生状态的线程有自己的内存空间,通过调用start()方法进入就绪状态。
新生状态
– 处于就绪状态线程具备了运行条件,但还没分配到CPU,处于线程就绪队列中,等待系统为其分配CPU。– 当系统选定一个等待执行的线程后,它就会从就绪状态进入执行状态,该动作称为“CPU调度”。
在CPU等待队列中,等待cpu的调度执行
就绪状态ready
在规定的时间片之内运行代码逻辑
运行状态runing
runable
自己所在线程暂停,让别的线程先运行
不会释放锁,Sleep时别的线程也不可以访问锁定对象。
sleep
自己线程执行过程中插入先执行另外一个线程,执行结束后再继续执行自己线程
join
重新进入等待队列,从runing状态转到ready状态
让出CPU的使用权,从运行态直接进入就绪状态。让CPU重新挑选哪一个线程进入运行状态。
yield
等待io设备
阻塞状态
1. 处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己运行,进入阻塞状态。2. 在阻塞状态的线程不能进入就绪队列。只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,随机抢占到CPU资源后,从原来停止的位置开始继续执行。
线程正常执行完成
stop强制结束
异常情况
死亡状态teminated
死亡状态是线程生命周期中的最后一个阶段。线程死亡的原因有三个:1.正常运行的线程完成了它的全部工作;2.线程被强制性地终止,如通过stop方法来终止一个线程【不推荐使用】;3.线程抛出未捕获的异常。
线程的生命周期
线程操作的相关方法
问题1:多个线程修改同一个共享数据,数据不一致问题问题2:多个线程获取共享数据(比如全局变量)时,每个线程都只能获取自己的那份数据,而无法获取真正的共享数据
安全问题场景
需要锁定一个监视器对象,也就是共享资源
▪ 同步的前提:▪ (1)必须有两个或两个以上的线程▪ (2)必须是多个线程使用同一资源▪ (3)必须保证同步中只能有一个线程在运行
使用同步代码块
示例
将需要同步的代码放到方法中
使用同步方法
– synchronized(obj){}中的obj称为同步监视器– 同步代码块中同步监视器可以是任何对象,但是推荐使用共享资源作为同步监视器– 同步方法中无需指定同步监视器,因为同步方法的监视器是this,也就是该对象本身
同步监视器
– 第一个线程访问,锁定同步监视器,执行其中代码– 第二个线程访问,发现同步监视器被锁定,无法访问– 第一个线程访问完毕,解锁同步监视器– 第二个线程访问,发现同步监视器未锁,锁定并访问
同步监视器的执行过程
同步监视器说明
解决安全问题的方式
线程安全问题
两个线程分别占用一份资源,同时又想占用对方的资源,但是两方谁也不先释放资源
死锁一般情况下表示互相等待,是程序运行时出现的一种问题
死锁
生产者和消费者的问题
notify()与 notifyAll()的区别
注意事项:以上方法都只能在同步方法戒者同步代码块中使用,否则会抛出异常
▪ Java提供了3个方法解决线程之间的通信问题 wait() notify() notifyAll()
线程通信
池化技术:频繁的创建和销毁线程比较浪费时间,因此可以将线程放到线程池中,需要的时候直接获取即可,省去创建和销毁的时间,通过可以更加方法的管理线程
1、使用线程池可以重复利用已有的线程继续执行任务,避免线程在创建和销毁时造成的消耗
2、由于没有线程创建和销毁时的消耗,可以提高系统响应速度
3、通过线程可以对线程进行合理的管理,根据系统的承受能力调整可运行线程数量的大小等
在实际使用中,线程是很占用系统资源的,如果对线程管理不善很容易导致系统问题。因此,在大多数并发框架中都会使用线程池来管理线程,使用线程池管理线程主要有如下好处
为什么需要线程池
1、先判断线程池中核心线程池所有的线程是否都在执行任务。如果不是,则新创建一个线程执行刚提交的任务,否则,核心线程池中所有的线程都在执行任务,则进入第2步;
2、判断当前阻塞队列是否已满,如果未满,则将提交的任务放置在阻塞队列中;否则,则进入第3步;
3、判断线程池中所有的线程是否都在执行任务,如果没有,则创建一个新的线程来执行任务,否则,则交给饱和策略进行处理
线程池执行所提交的任务过程
1.阻塞队列中任务、核心线程池中的线程、非核心线程池中的线程, 这3者之间如何转化?执行顺序是怎样的?
疑问
线程池工作原理
ScheduledThreadPoolExecutor:定时任务线程池类,用于实现定时任务相关功能,实现了ScheduledExecutorService
ScheduledExecutorService:继承自ExecutorService,对ExecutorService做了一些扩展,增加一些定时任务相关的功能
ThreadPoolExcutor:普通线程池类,包含最基本的一些线程池操作相关的方法实现
ForkJoinPool:新型线程池类,JAVA7中新增的线程池类,基于工作窃取理论实现,运用于大任务拆小任务,任务无限多的场景
AbstractExecutorService:抽象类,运用模板方法设计模式实现了一部分方法,实现了ExecutorService
ExecutorService:线程池次级接口,继承自Executor,对Executor做了一些扩展,增加了一些功能
Executor:线程池顶级接口
Executors:线程池工具类,定义了一些快速实现线程池的方法
线程池体系结构
newCachedThreadPool
newFixedThreadPool
newSingleThreadPool
ThreadPoolExecutor
newSingleThreadScheduledExecutor
newScheduledThreadPool
ScheduledThreadPoolExecutor
newWorkStealingPool
ForkJoinPool
线程池的分类
能接受新提交的任务,并且也能处理阻塞队列中的任务
running
关闭状态,不再接受新提交的任务,但却可以继续处理阻塞队列中已保存的任务
shutdown
不能接受新任务,也不处理队列中的任务,会中断正在处理任务的线程。
stop
如果所有的任务都已终止了,workerCount (有效线程数) 为0,线程池进入该状态后会调用 terminated() 方法进入TERMINATED 状态
tidying
在terminated() 方法执行完后进入该状态,默认terminated()方法中什么也没有做
terminated
线程池的生命周期
corePoolSize:核心线程数
maximumPoolSize:线程池能创建线程的最大个数
keepAliveTime:空闲线程存活时间
unit:时间单位,为keepAliveTime指定时间单位
workQueue:阻塞队列,用于保存任务的阻塞队列
threadFactory:创建线程的工程类
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
handler:饱和策略(拒绝策略)
参数列表
线程池的创建
如果当前运行的线程少于corePoolSize,则会创建新的线程来执行新的任务;
如果运行的线程个数等于或者大于corePoolSize,则会将提交的任务存放到阻塞队列workQueue中;
如果当前workQueue队列已满的话,则会创建新的线程来执行任务;
如果线程个数已经超过了maximumPoolSize,则会使用饱和策略RejectedExecutionHandler来进行处理。
executor方法的执行逻辑
submit是基方法Executor.execute(Runnable)的延伸,通过创建并返回一个Future类对象可用于取消执行和/或等待完成。
execute和submmit方法的区别
2、shutdown只是将线程池的状态设置为SHUTDOWN状态,然后中断所有没有正在执行任务的线程
关闭线程池,可以通过shutdown和shutdownNow两个方法
原理:遍历线程池中的所有线程,然后依次中断
线程池的关闭
高阶知识:线程池
线程
ip地址
端口
通讯协议
网络三要素
InetAddress类的api处理
7层协议
开放互联参考模型
OSI
四层的通讯协议
tcp/ip
网络模型
安全,传输的数据报比较大
稳定的连接,必须要经过三次握手以及四次分手
TCP
不安全,传输的内容比较少
不需要稳定的连接,直接发送,不用管对方是否接受
UDP
套接字
Socket
开发服务端的端口等待连接
ServerSocket
DatagramSocket
DatagramPacket
网络编程
网络
Lambda表达式是 Java8 中最重要的新功能之一。Lambda 表达式可以替代只有一个抽象函数的接口实现,告别匿名内部类,代码看起来更简洁易懂。Lambda表达式同时还提升了对集合、框架的迭代、遍历、过滤数据的操作。lambda可以极大的减少代码冗余,同时代码的可读性要好过冗长的内部类,匿名类
介绍
表达式案例
1:函数式编程2:参数类型自动推断3:代码量少,简洁
表达式的语法及案例
只有一个抽象方法(Object类中的方法除外)的接口是函数式接口
Supplier 代表一个输出Consumer 代表一个输入BiConsumer 代表两个输入Function 代表一个输入,一个输出(一般输入和输出是不同类型的)UnaryOperator 代表一个输入,一个输出(输入和输出是相同类型的)BiFunction 代表两个输入,一个输出(一般输入和输出是不同类型的)BinaryOperator 代表两个输入,一个输出(输入和输出是相同类型的)
任何有函数式接口的地方
如果函数式接口的实现恰好可以通过调用一个静态方法来实现,那么就可以使用静态方法引用
静态方法引用
如果函数式接口的实现恰好可以通过调用一个实例的实例方法来实现,那么就可以使用实例方法引用
实例方法引用
抽象方法的第一个参数类型刚好是实例方法的类型,抽象方法剩余的参数恰好可以当做实例方法的参数。如果函数式接口的实现能由上面说的实例方法调用来实现的话,那么就可以使用对象方法引用
对象方法引用
如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用
构造方法引用
方法引用的分类
方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法,方法引用提供了一种引用而不执行方法的方式,如果抽象方法的实现恰好可以使用调用另外一个方法来实现,就有可能可以使用方法引用
方法的引用
应用场景
lambda表达式
javase
0 条评论
回复 删除
下一页