JAVA核心知识点整理
2024-07-29 15:59:38 0 举报
AI智能生成
Java语言基础是学习Java的第一步,包括数据类型、运算符、控制语句等。Java提供了丰富的数据类型,如整型、浮点型、字符型、布尔型等,这些数据类型为程序员提供了灵活的编程选择。运算符用于执行各种算术、逻辑和位操作,控制语句则用于控制程序的流程。模板对Java的核心知识点进行了全面整理和深入解析,包括Java语言基础等内容,可以帮助大家更好地掌握Java编程技术,提高开发能力。在实际应用中,要注重练习和实践,不断提升自己的编程水平。
作者其他创作
大纲/内容
高级
异常
Throwable
Error
jvm处理不了的,出错程序直接停止
像栈溢出、堆溢出、方法区溢出这些
Exception
可以进行处理,处理完程序可以继续正常运行,如果不处理,程序直接停止
运行时异常〔非受检)
下标越界、类型转换异常、空指针、运算符异常、非法参数
非运行时异常(受检)
找不到文件
未知host
处理
try catch finally
有资源要释放的用try resourcetry
不处理,往调用者抛,在方法声明上通过throws
手动抛异常
throw
多线程并发
进程和线程的区别看操作系统去
资源分配的单位:进程
调度单位:线程
并发和并行的区别也看操作系统去
并发:时间段
并行:时刻
死锁
看操作系统去
互斥
请求和保持
不可抢占
循环等待
死锁的避免
避免一个线程向时获取多个锁
避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源
使用try Lock
线程的创建方式
继承thread类
问题:不支持多继承
实现Runnable接口
实现Callable接口〈有返回值、-异常),用FutureTask接收返回值
线程池
线程生命周期
NEW
RUNNABLE
wait
time waiting
block
terminate
线程常用方法
start()|注意和run()区别,直接调用run是在主线程里执行方法,调用start()本质是调用了native方法向操作系统申请了资源
join,在一个线程中调用其他线程的join方法,实现同步效果
sleep,记住不释放锁就行了
中断
interrupt()
打断线程
islnterrupted()
判断打断线程的状态,不会清除打断标记
interrupted(),静态方法
判断线程状态,会清除打断标记
线程属性
线程id
线程名
线程优先级
线程状态
ThreadLocal
空间换时间,每个线程拥有自己的一份副本变量
ThreadLocal只是一个壳子,内部使用的ThreadLocalMap类才是实质
ThreadLocalMap
当一个线程调用ThreadLocal的Set方法时,首先会从尝试直接从当前Thread的threadLocals或员变量获取,如果这个成员变量为null,则表示当前线程还没有初始化ThreadLocalMap,接着会调用createMap方法初始化当前线程的ThreadLocalMap对象,.key值为当前的ThreadLocal对象,创建完成后将这个对象赋值给当前Thread的threadLocalMap对象。
InheritableThreadLocal
InheritableThreadLocal继承自ThreadLocal,重写了childvalue. getMap和"createMap方法,实现父子线程共享的核心是对于childvalue的重写。结合-Thread类的init方法来看,Thread对象在创建的时候,如果父类的inheritableThreadLocals不为空,则会调用ThreadLocal的createlnheriteMap方法进行创建,接着通过childvalue方法获取父线程的值,把父线程的inheritableThreadLocals的值赋值到新的ThreadLocalMap对象
线程安全问题(这里不写,看JVM去)
线程通信
object类里的wait、notify等方法
JUc里的await,signal等方法
LockSupport里的park、unpark
并发机制的底层实现原理(看JVMq)
线程池
优点
降低资源消耗
提高线程响应速度
提高线程的可管理性
线程池的主要参数
核心线程数
最大线程数
空闲线程存活时间
存活时间的单位
等待任务的阻塞队列
创建线程的工厂
拒绝策略
直接抛出异常
让调用者自己执行
丢弃最近的―个任务,执行当前任务
.不处理,丢弃
线程池的处理流程
提交一个任务,首先判断核心线程池是否已满
如果没满,创建线程执行任务
如果满了,接着判断队列是否已满
如果没满,将任务存储到队列里
如果满了,判断线程池是否已满
如果没满,创建线程执行任务
如果满了”按照策咯处理无法执行的任务
线程池的关闭
shutdown
比较柔性,先设置线程池状态,等待正在执行的线程执行完成在关闭
shutdownNow
强硬,直接停止正在执行的线程,关闭线程池
如何合理的配置线程池
①判断任务特性
CPU密集型、IO密集型或者是混合型
②使用有界队列
③合理监控线程池
常用API
String
查找
indexOf
charAt
截取
subString
split
替换
replace
大小写转换
去空
trim
开头结尾
length
getbytes
toString
StringBuilder
StringBuffer
曰期类
System类
Runtime类
集合
Collection
List(有序可重复)
ArrayList
数组、线程不安全
LinkedList
双向链表
Vector
数组,线程安全
set(无序不可重复)
HashSet
底层是HashMap的key
LinkedHashSet
TreeSet
Map(K,V)
HashMap
数组+链表+红黑树
HashTable数组+链表
Properties
TreeMap
关于equals和hashcode的面试题,我的建议是直接看源码注释,哪里有什么花里胡哨的,人家注释里hashcode方法就是写给map用的,还有这里方法的逻辑关系,是从源码里面推出来的,源码里hashcode结果一致还会接着用equal判断一致,equal-一-致,那hashcode肯定一致啦
Collections工具类
排序
查找
复制,替换
添加
同步
泛型
泛型工作中偶尔会用到(封装Result类)
类
接口
方法
java的泛型是编译擦除的
反射
反射工作中基本没用到,但是理解这个很重要,对看源码帮助很大
IO
老实说我不是很想讲这个,工作中要使用基本都是调人家封装好的,像hutool和guava、 apach的lang
网络编程
老实说我这个也不想讲,写业务根本就没有地方给你用网络编程,除非你自己造
新特性
8
Lambda表达式
函数式接口
Stream APl
基础语法
变量
基本数据类型
整型
byte
short
int
long
浮点型
float
double
字符型
char
布尔
true
false
自动类型握升
小的会自动转大的
强制类型转换
(5强制类型)
丢失精度
甚本数据类型和String的运算
只能用+号运算,结果一定是String
byte、short、char在运算中会转为int
引用数据类型—类、接口、数组
运算符
算术运算符
不细讲了,主要是*+和--两个说一下
++
直接使用i++和++i没区别
结合赋值符使用
i++,先用i,在加1
++i,先加1再用i.
--
减减同上
赋伯运算符
主要是说一下+=、-=这类的
这类会带有险式的强制类型转换,转为=号左边的
比较运算符
没说法
逻辑运算符
面试问的比较多的是|和||的区别、&和&&的区别
两个的,如果左边第一个条件不满足,就会直接返回false;一个的两边都得判断完才能得出结果
流程控制
顺序
没哈好说的,顾名思义
分支
if-else
这个没哈好说的,有手就行
switch-case
这块涉及到面试问的比较多的一个题
switch表达式在jdk7后支持String,本质是使用String的Hash值
break和default留意一下就可以了
上面两个效率比较
网上的课程说法是能用switch的可以尽量用,效率会高一点,但是我个人实际编码过程中是没怎么用过,直接if就完事了,review的时候要领导提意见了再说
循环
for
while
do...while
至少执行一次
数组
声明+初始化
个人习惯例: " int[arr=new int[?];或者int[] arr= {?,?,?,?,}
使用
长度arr.length
索引 arr[i]
遍历
在有IDE加持的情况下,这些基础操作都不是事儿,代码提示一把梭
多维数组
有一说一我真没见过用多维数组的,甚至一维都少见,更甚数组都少见到用的,基本都是集合框架那块用的多,数组一是定长,而是提供的方法支持没有集合那么多,用起来确实没集合框架那么顺手
对应工具类Arrays
用的比较多的就数组拼接、sort排序、二分查找、数组复制、数组比较
数组填充我还真没用过
数组异常
下标越界
空指针
面对对象
面向对象和面向过程的区别
1.1面向对象
面向对象是将构成问题的事物分解成一个个的对象,使用对象去描述事物在解决问题过程中的行为,而不是专注于使用对象去完成一个步骤
1.2面向过程
面向过程简而言之就是将一个问题的解决划分为多个步骤,使用函数实现一个个的步骤,然后再按照顺序进行调用
1.3总结
两者在解决问题时,专注的角度不同,面向对象正如这个名称而言,它更关注问题中设计到了那些对象,有什么属性,涉及到什么行为,去将这样的对象一个个实例化,再通过对象之间的行为去解决一个问题,而,面向过程也是,关注点在于第一步要做什么、第二部要做什么,这样一个循序渐进的过程。
类
成员变量
成员方法
局部变量
构造器
默认提供无参构造,如果你自己写了构造函数,则不提供无参构造
对象
匿名对象
对象的创建方式
new
clone
反序列化
反射
这里面的很多细节有一说一我很想讲,,但是我不知道怎么讲
像成员变量和局部变量和静态方法啥的区别,你初学的时候得死记硬背觉得很抽象,但是当你往JVM学习之后就好理解,它们的区别在于它们在运行时数据区中存储的位置不一样,导致了它们的声明周期、默认值、作用范围等的不一样,我个人不太喜欢死记硬背,别人问我的时候我也不能立刻答上来,但是我会从JVM的角度去梳理、对比它们,总而言之,知识的融会贯通很重要。
举个例子
局部变量在栈帧的局部变量表上,它在编译时就决定了栈帧的大小,所以对于局部变量,你必须进行初始化才能使用,编译器不帮你设置零值
成员变量基于对象的创建过程,这个过程有一个设置零值的操作,所以可以只进行声明,不进行初始化
静态变量在类加载时处理,它也有一个零值的设置阶段,所以也可以只声明不初始
然后就是作用范围,类先加载,然后对象才能在创建,所以在静态方法里肯定是不能用成员方法和成员变量的
总之这些东西罗里吧嗪一堆很难说清楚的,但是你从JVM的角度去推,"思路就很清晰
面向对象的特点
封装
封装简而言之就是将类的内部细节隐棘,只对外提供公共的访问方法。JavaBean就是一个很好的例子,将字段私有化,只对外提供Setter和Getter方法进行访问。
封装的优点在于可以提高代码的安全性、降低耦合,
继承
继承就是将多个类所拥有共同属性和行为向上抽取,形成一个父类。子类通过extends去继承这个父类就能够获得公共的行为和属性
继承的优点在于可以提高代码的复用性,但是问题也很明显,它破坏了封装性,并且是一种强耦合
PS:继承应该遵循里氏替换原则,子类对象必须能够替换掉所有父类对象。
继承注意点:
1、子类拥有父类非private的属性和方法。.《(另一种说法是。子类也拥有父类的私有属性和方法,但是它并没有权限去访问他们》
2、子类可以拥有自己属性和方法,即子类可以对父类进行扩展
3、子类可以用自己的方式实现父类的方法(重写)
多态
编译时多态
编译时多态指对象引用所调用的方法在编译期就确定了,主要指方法的重载
运行时多态
运行时多态指程序中定义的对象引用所指向的具体类型在运行期间才确定,主要.指方法的重写
运行时多态的必要条件:继承、方法重写、父类引用指向子类对象《(向上转型》
PS:重写发生在父子类之间,并有一下规范:子类重写的方法的返回值类型婴小于或者等于父类,返回值也一样,而方法的权限修饰符要大于父类,这是为了符合设计模式关于类设计的五大原则之一里氏替换
多态的优点在于提高了程序的可拓展性
面向对象的SOLID原则
单一职责
让一个类只做一种类型责任,当这个类需要承当其他类型的责任的时候,就需要分解这个类
开闭原则
对扩展是开放的,而对修改是封闭的
里氏替换
当一个子类的实例应该能够替换任何其超类的实例时,它们之间才具有is-A关系
倒置依赖
高层模块不应该依赖于低层模块,二者都应该依赖于抽象
抽象不应该依赖于细节,细节应该依赖于抽象
接口隔离
不能强迫用户去依赖那些他们不使用的接口。换句话说, 使用多个专门的接口比使用单一的总接口总要好
访问权限问题
public
公共所有人都能访问-
默认
仅限同一个包下的类能访间
protect
仅限同一个包下的类以及它的子类能访问
private
只有当前类能访问
修饰问题
方法、字段
都可以修饰
类
public
默认
构造器问题
重载和重写
重载
同一个类,方法名一样,参数列表不同
重写
this和super
this
本质是一个指针,在局部变量表索引0的位置
super
关键字
接口和抽象类
属性
抽象声明的属性都是静态常量;抽象类没限制
方法
接口只能声明方法不能实现方法,但是jdk8有默认方法;抽象类可以声明也可以实现方法
构造函数
接口不能有构造函数,抽象类可以有
多继承
接口支持多继承,抽象类不支持
Object类的方法
反射用的
getClass
clone
集合用的
equals
haschode
toString
并发用的
wait
notify
notify all
JVM用的
触发垃圾回收的方法,已经不用了
内部类(老实说我就没用过这玩意,这玩意源码里看到的比较多)
成员内部类
静态内部类
局部内部类
匿名
非匿名
枚举
本质也是类,但是对象个数有限
枚举我工作中没有从零写过,都是在已有的枚举上加,像自定义状态码啥的就用-枚举,至于它有什么方法,有一说一我没怎注意,IDEA里·一下看哪个能用就用哪个。。。 。
注解
常用注解
重写检查
抑制警告
弃用标识
元注解
@Document
被javadoc记录
@Target
注解作用范围
@Retention
生命周期
自定义的一律RUNTIME
@lnherited
允许子类继承父类注解
自定义注解
声明
使用
读取(用反射)
包装类
为什么要包装类
基本数据类型不符合面向对象特性
留意缓存值,面试有问
直接记,除了浮点都有缓存
拆箱和装箱看看就好了,反正也不是你手动拆或者装的
包装类的APl,没特别留意过
字符串、基本数据类型、和包装类间转换
大小写转换
进制转换
比较
0 条评论
下一页