导图社区 Java核心知识(基础)
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。本思维导图是对java基础知识总结,比较全面,干货,实际开发总慢慢的总结的,花费了大量的时间,希望对你有帮助!适用于java面试,软件开发,架构师,Java,互联网,程序,程序员,阿里面试的朋友。
编辑于2021-04-07 23:41:40Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。本思维导图是对java基础知识总结,比较全面,干货,实际开发总慢慢的总结的,花费了大量的时间,希望对你有帮助!适用于java面试,软件开发,架构师,Java,互联网,程序,程序员,阿里面试的朋友。
基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
下列思维导图分支内容包括:数据库,数据库考试,数据库面试,计算机。
社区模板帮助中心,点此进入>>
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。本思维导图是对java基础知识总结,比较全面,干货,实际开发总慢慢的总结的,花费了大量的时间,希望对你有帮助!适用于java面试,软件开发,架构师,Java,互联网,程序,程序员,阿里面试的朋友。
基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
下列思维导图分支内容包括:数据库,数据库考试,数据库面试,计算机。
Java核心知识(基础)
java平台
编译运行
解释执行
解释器在运行时逐行将代码翻译成机器码,交给机器执行。
编译执行
存在JIT编译器(Just In Time Compile 即时编译器)以方法为单位把经常运行的代码作为"热点代码"编译成本地平台相关的机器码,并进行各种层次的优化。
AOT编译器
Java 9提供的直接将所有代码编译成机器码执行。
解释执行和编译执行有何区别
一个是同声传译,一个是放录音
类加载
类加载器
bootstrap、application、Extension Class-loader
类加载过程
加载、链接(验证,准备,解析)、初始化
运行机制
实例化顺序(重上往下)
父类静态代码块>子类静态代码块>父类成员>父类非静态代码块>父类构造方法>子类成员>子类非静态代码块>子类构造方法
执行顺序
public class MaxCount { static { System.out.println("xxx"); } { System.out.println("yyy"); } public MaxCount() { System.out.println("lll"); } public static void main(String[] args) { System.out.println("fff"); MaxCount count = new MaxCount(); } }
执行顺序优先级:静态块>main()>构造块>构造方法
静态块:用static{}申明,JVM加载类时执行,仅执行一次
构造块:类中直接用{}定义,每一次创建对象时都执行
值类型与引用类型
传递
只有基本数据类型和String s="hello";的传递是值传递,其他对象传递都是引用传递。 数组属于对象,所以是引用传递,引用传递只要不重新开辟内存空间,修改都是有效的。如果重新开辟空间,则引用的对象会被解析为同名的局部变量,原引用消失。
面向对象的基本要素
封装
隐藏内部代码,提高安全性和简化编程。
继承
复用现有的代码
多态
改写对象的行为
方法重载(overloading)
简介
让类以统一的方式处理不同类型的数据的一种手段,多态的体现。
在一个类中 存在两个或者两个以上的同名函数,称作为方法重载。
要求
函数名要一致。
形参列表不一致
与返回值类型无关。
方法重写(overriding)
简介
父类的功能无法满足子类的需求。
必须要存在继承的关系。
子父类出了同名的函数,这个我们就称作为方法的重写。
要求
两同
方法名与形参列表必须一致。
两小
子类返回值类型必须是父类返回值类型的子类(若返回值类型是引用时),若是基本数据类型,则必须完全一致。
子类抛出的异常类型要小于或者等于父类抛出的异常类型。
一大
子类的权限修饰符必须要大于或者等于父类的权限修饰符。
覆盖问题
子类不能覆盖父类中声明为final或者static的方法
子类必须覆盖父类中声明为abstract的方法,或者子类也必须声明为abstract
子类覆盖父类中的同名方法时,子类的方法声明也必须和父类中被覆盖的方法的声明相同
抽象
类是对现实世界所有载体的抽象
Java的引用
简介
java语言中,除了原始数据类型,其他类型都是引用类型,指向不同的对象
不同的引用,体现的是对象不同的可达性状态和对垃圾收集的影响
分类
强引用
Object o =new Object();
普通对象的引用,强引用指向一个对象,表明对象还活着,垃圾收集器不会碰这种对象。
普通对象如果没有其他引用关系,只要超过引用的作用域或者显示将引用赋值为null,就可以被垃圾收集了
软引用
SoftReference
相对强引用弱化一点的引用,让对象避免一些垃圾收集,JVm内存不足时,才会试图收集软引用指向的对象,JVM在抛出OutOfMemoryError之前,才会清理软引用指向的对象。
通常用来实现内存敏感的缓存,如果还有空闲内存,可以暂时保留缓存,内存不足时清理掉,保证了使用缓存的同时,不会耗尽内存,比如图片缓存。
弱引用
WearkReference
并不能是对象避免垃圾收集,仅仅提供一种访问弱引用状态下对象的途径。
可以用来构建一种没有特点约束的关系,维护一种非强制性的映射关系,如果获取时对象还在就使用,否则重新实例化,也是很多缓存实现的选择。
幻象引用
Object o =new Object(); o=null
也叫作虚引用,不能通过他访问对象,仅仅提供一种确保对象被finalize后,做某些事情的机制。
通常用来做Post-Mortem清理机制,Cleaner机制,监控对象的创建和销毁。
可达性级别
强可达
一个对象可以有一个或多个线程可以不通过各种引用访问到的情况,我们创建一个对象,创建他的线程对他就是强可达。
软可达
我们只能通过软引用才能访问到对象的状态
弱可达
无法通过强引用或者软引用访问,只能通过弱引用访问的对象,接近finalize状态,弱引用被清除,就是finalize条件。
幻象可达
没有强,软,若引用关联,且finalize过了,只有幻象引用指向这个对象的时候。
不可达
对象可以被清除了。
抽象类与接口
接口
概念
接口是对行为的抽象,是抽象方法的集合,利用接口可以达到API定义和实现分离的目的
特点
不能实例化。
支持多重继承
没有构造方法,没有非静态方法实现,要么是抽象方法,要么是静态方法
只能包括public函数及public static final常量
抽象类
概念
抽象类是不能实例化的类,用abstract关键字修饰,期目的是代码重用。
特点
除了不能实例化,形式上和一般java类没有太大区别
不支持多重继承
有构造方法,不能实例化
动态代理&反射
编程语言类型
动态类型
运行时检查,缺点是生成代理对象和调用代理方法都要额外花费时间。
静态类型(java)
编译时检查,事先写好代理类,可以手工编写,也可以用工具生成,缺点是每个业务都要对应一个代理类,非常不灵活。
反射
概念
反射最大的作用之一就在于我们可以不在编译时知道某个对象的类型,而在运行时通过提供完整的”包名+类名.class”得到。注意:不是在编译时,而是在运行时。
功能
1.在运行时能判断任意一个对象所属的类。2.在运行时能构造任意一个类的对象。3,在运行时判断任意一个类所具有的成员变量和方法。4.在运行时调用任意一个对象的属性和方法。
场景
反射技术常用在各类通用框架开发中。因为为了保证框架的通用性,需要根据配置文件加载不同的对象或类,并调用不同的方法,这个时候就会用到反射——运行时动态加载需要加载的对象。
实例
反射操作
简介
在运行,动态获取这个类的信息
三种方法获取类
1、
Class clazz1 = User.class;
2、
Class clazz2 = Class.forName("com.hly.java.reflect.User");
3、
User user = new User(); Class clazz3 = user.getClass();
实例
反射创建无参类
//创建反射对象,调用无参构造方法 Object newInstance1 = clazz1.newInstance(); //设置私有属性的值 Field fieldUsername = clazz1.getDeclaredField("username"); //允许操作私有成员 fieldUsername.setAccessible(true); //设置值 fieldUsername.set(newInstance1,"123"); //类型转换 User user1 = (User) newInstance1; //输出 System.out.println(user1.getUsername());
反射创建有参类
//实例化有参构造方法 Constructor<?> constructor = clazz3.getConstructor(String.class, String.class); User newInstance2 = (User) constructor.newInstance("123", "123"); //System.out.println(newInstance2.getUsername());
常用API
获取该类的所有方法
getDeclaredMethods []
子主获取该类的返回值题
getReturnType()
获取传入参数
getParameterTypes()
获取该类的所有字段
getDeclaredFields()
允许访问私有成员
setAccessible
动态代理
概念
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在两者之间起到中介的作用
所谓动态代理,就是实现阶段不用关心代理谁,而是在运行阶段才指定代理哪个一个对象,也就是运行时动态生成代理类(不确定性)。如果是自己写代理类的方式就是静态代理(确定性)。
组成要素
抽象类接口
被代理类(具体实现抽象类的接口)
动态代理类(实际调用被代理类的方法和属性的类)
场景
包装RPC调用,面向切面编程AOP,JDBC,Servlet
方式
JDK动态代理
基于接口实现
CGlIB
基于继承当前类的子类实现
异常处理
实现类
Throwable
Error
StackOverflowException
OutOfMemoryError
Exception
IOException(checked)
RuntimeException
NullpointerException
ArrayIndexOutOfBoundsException
throw & throws
throw
抛出一个异常
throws
声明可能会抛出一个异常
类型
Exception
概念
可以被抛出和捕获异常
分类
checked
可检查异常在源代码里必须显式地进行捕获处理,这是编译期检查的异常
unchecked
不检查异常就是所谓的运行时异常,类似空指针,通常可以编码避免错误,根据需要来判断是否需要捕获。
Error
概念
正常情况下,不大可能出现的情况,导致程序宕机,不便于也不需要捕获
处理要求
不要生吞异常
尽量不要捕获类似Exception这样的通用异常,而是应该捕获特定异常
java 每实例化一个 Exception,都会对当时的栈进行快照,比较重的操作。
try-catch会产生额外的性能开销,最好是包括需要检验异常的代码,不要包含过长代码,影响JVM对代码进行优化
ps
finally一定会执行,如果catch中return了,catch中的return会等finally中的代码执行完后,才会执行。
final,finally,finalize
区别
final
final修饰的类不能被继承
final修饰的变量不能被修改
final修饰的方法不能被重写
finally
保证重点代码一定要被执行的一种机制
使用try-finally,try-catch-finally关闭JDBC连接等
finalize
Object的一个方法,java虚拟机在实现gc时候调用回收对象的这个方法。
使用要求
无法保证 finalize 什么时候执行,执行的是否符合预期,使用不当会影响性能,导致程序死锁,挂起
String,StringBuffer,StringBuilder
区别
String
String是对象,典型的Immutable类,被声明为final,所有属性不可变,保证了基础的线程安全,由于不可变性,拼接,裁剪等动作,都会产生新的String对象。 PS:String="123" 会被分配到常量池中,new String()会被分配到堆内存中。
StringBuffer
在各种修改数据的方法上添加了synchronized解决拼接产生的问题提供的一个类,线程安全的可修改字符序列,带来了额外开销。
StringBuilder
去掉了线程安全的部分,有效减小了开销
特点
JDK8中非静态的拼接会自动被javac转换为StringBuilder操作
StringBuilder和StringBuffer底层使用了可修改的char,JDK9改为了byte,值可以改变,对象引用不会改变,构造的过程中,先申请字符数组,超过默认大小后,会创建更大的数组,并将原先数组复制过来,丢弃原来数组。
String使用频繁,引入了字符串常量池,创建一个字符串时,首先检查池中是否有相同的字符串对象有则直接取出,没有则创建对象把对象放入池中,new方法创建的对象不检查字符串池,直接在堆区或者栈区创建新的对象。Object obj = new Object() obj是对象的引用,位于栈中,new Object()产生的数据才是对象,位于堆中。
new String()提供了intern()方法,如果池中有等于String对象的字符串,则返回池中的字符串,如果没有则在池中创建一个字符串并返回该字符串,如果堆中有该字符串池中没有,则将此对象指向堆中的引用放入池中,并返回堆中的对象引用。
int和Integer
int
概念
int是java8个原始数据类型之一,java号称一切都是对象,但原始数据类型是例外。
Integer
概念
Integer是int的包装类有一个int类型的字段存储数据,并提供了基本操作,比如数学运算与字符之间的转换。引入了自动装箱和拆箱功能。
自动装/拆箱
一种语法糖,java平台自动进行一些转换,保证了不同写法在运行时等价,发生在编译时期,生成的字节码是一致的。javac会自动把装箱转换为Integer.valueOf(),拆箱替换为Integer.intValue()。
源码
缓存
java5添加了静态工厂方法valueOf(),调用时会利用一个缓存机制,这个值默认为-128-127之间
List
接口
Collection
List
特点
List集合允许元素重复。
元素的顺序是对象插入的顺序。
类似于数组,用户可通过索引访问集合中的元素。
接口
Vector
特点
线程安全的动态数组,使用了Synchronized实现同步,扩容时会提高1倍。
内部元素以数组形式顺序存储,适合随机访问,插入和删除性能差。
ArrayList
特点
应用更加广泛的动态数组实现,不是线程安全的,扩容增加50%。
内部元素以数组形式顺序存储,适合随机访问,插入和删除性能差。
LinkList
特点
双向链表,不是线程安全的。
进行节点插入,删除比较高效,随机访问性能较差。
Set
特点
不按特定方式排序,简单把对象加入集合。
不能包含重发对象,只允许一个Null。
接口
HashSet
特点
不保证数据有序。
依靠hashCode(),equals()区分重复数据。
实现Set接口,由HashMap支持。
允许使用null元素。
原理
基于HashMap实现,底层使用HashMap保存所有元素。
TreeSet
特点
保存数据有序,支持自然顺序访问,添加,删除效率较低。
依靠Comparable区分重复数据。
实现了Set接口,SortedSet接口。
保存自定义类的对象,定义所在的类需要实现Comparable
遍历集合时按自然顺序递增排序,也可按比较器递增排序。
LinkedHashSet
特点
构建了一个记录插入顺序的双向链表,提供了按照插入顺序遍历的能力。
保证了常数时间添加,删除,包含等操作,需要维护链表开销,性能略低于HashSet。
Iterator
简介
可以遍历任何Collection接口,并允许在迭代的过程中删除元素。
用法
List list = new ArrayList(); Iterator iterator = list.iterator();
Map
接口
Map
特点
以键值对的形式存储和操作数据的容器类型。
接口
AbstractMap
接口
HashMap
特点
不是同步的
支持null键和值,只能有一个key为null,可多个value为null
原理
HashMap基于hash算法实现,我们通过put进行存储,get进行获取,当传入key时, 会根据key.hashCode()计算出hash值,根据hash值将value保存在bucket里。当计 算出的hash值相同时,我们成为hash冲突,HashMap的做法是使用链表和红黑树存储 hash值相同的value。
接口
LinkedHashMap
特点
提供的遍历顺序符合插入顺序
维护了一个双向链表
ConcurrentHashMap
特点
基于lock实现锁分段技术。首先将Map存放的数据分成一段一段的存储方式,然后给每一段数据分配一把锁,当一个线程占用锁访问其中一个段的数据时,其他段的数据也能被其他线程访问。
保证了多线程运行环境下的数据访问安全性,而且性能上有长足的提升。
TreeMap
特点
不允许对象为null
集合中的对象存在一定顺序,整体顺序由键的顺序决定,通过Comparator或Comparable来决定
Hashtable
特点
同步,线程安全,性能开销大,不支持null键和值,不建议使用
约定
equals相等,hashCode一定要相等,hashcode相等,equal不一定相等。
重写equal还要重写hashcode
hashcode()继承于Objec类,hashcode码默认为对象的内存地址, 两个相同含义的对象,比较也不相等。equal()比较的是对象的地址。
HashMap比较key是否相等,需要使用这两个函数,先求出key的hashcode(),若相等,再比较equal,equal相等则认为他们相等。
若只重写hashcode(),不重写equal(),比较equal时只是比较他们是否为同一对象,所以必须两个方法一起重写。
重载hashcode()为了同一个key能得到相同的HashCode,重载equal()为了向HashMap表名当前对象和key上所保存的对象是相同的。
I/O
术语
同步/异步
同步
同步是一种可靠的有序运行机制,当我们进行同步操作时,后续的任务是等待当前调用返回,才会进行下一步。
异步
其他任务不需要等待当前调用返回,通常依靠事件,回调机制来实现任务间的次序关系。
阻塞/非阻塞
阻塞
进行阻塞操作时,当前线程会处于阻塞状态,无法从事其他任务,只有当条件就绪才能继续,比如ServerSocket新建连接。
非阻塞
不管IO操作是否结束,直接返回,响应操作在后台继续处理。
种类
功能
输入流input
输出流output
类型
字节流
按 8 位传输以字节为单位输入输出数据
字符流
按 16 位传输以字符为单位输入输出数据
分类
File
特点
代码简单直观
效率和扩展性存在局限性,容易成为性能的瓶颈
分类
InputStream/OutputStream
用于读取和写入字节,例如操作图片文件。
Reader/Writer
用于操作字符的,增加了字符解码等功能。
BufferOutputStream
带缓冲区的实现,避免频繁的磁盘读写。
Socket
NIO
特点
可以构建多路复用,同步非阻塞IO程序,同时提供了更接近操作系统底层的高性能数据操作方式。
AIO
特点
引入了异步非阻塞IO方式
异步IO操作基于事件和回调机制,应用操作直接返回,不会阻塞在那里,当后台处理完成,操作系统会通知响应线程进行后续工作。
举例
BIO(同步阻塞)
快递员通知你有一份快递会在今天送到某某地方,你需要在某某地方一致等待快递员的到来。
NIO(同步非阻塞)
快递员通知你有一份快递会送到你公司的前台,你需要每隔一段时间去前台询问是否有你的快递。
AIO(异步非阻塞)
快递员通知你有一份快递会送到你公司的前台,并且前台收到后会给你打电话通知你过来取。
基础语法
==比较的是什么
基本类型
两边是基本类型,比较数值是否相等。
比较对象
两个对象的内存引用,两个对象完全相同时,返回true。
equal比较的是什么
引用比较
默认情况下是引用比较
值比较
很多类重写了该方法,编程了值比较 如Integer,String
&与&&的区别
&
按位与
逻辑与
&&
短路运算
左边的表达式是false,右边的表达式会被短路掉,不会进行运算
u!=null&&u!="",二者顺序不能交换,也不能使用&,否则会产生空指针异常
||和|
||和|都是表示“或”,区别是||只要满足第一个条件,后面的条件就不再判断,而|要对所有的条件进行判断。
Math. round(-1. 5)的值
等于 -1,因为在数轴上取值时,中间值(0.5)向右取整,所以正 0.5 是往上取整,负 0.5 是直接舍弃