深入解读:JDK与JRE的区别
JDK提供了完整的Java开发工具和资源,包括编译器、调试器和其他开发工具,满足开发人员的各种需求。
JRE则相对更为基础,它只提供了Java程序运行所需的环境,包含了Java虚拟机(JVM)和Java核心类库,不包含开发工具。在部署Java应用程序时,只需要安装JRE来运行程序即可。
JDK< JRE , 开发工具 >
JRE< JVM , 核心类库 >
Java 中 boolean 占多少字节?
《Java 虚拟机规范》提议:
如果 boolean 是 “单独使用”:boolean 被编译为 int 类型,占 4 个字节;
如果boolean 是以 “boolean 数组” 的形式使用:boolean 占 1 个字节,Java 虚拟机直接支持 boolean 数组,通过 newarray 指令创建 boolean 数组,然后通过 byte 数组指令 baload 和 bastore 来访问和修改 boolean 数组。
但是,具体占用大小仍然取决于每个虚拟机的具体实现是否按照规范来
其他基本数据类型占用字节数
char:2B;
byte-short-int- long:1-2-4-8B;
float-double:4-8B
3.用最有效率的方法计算 2 乘以 8
2 << 3。位运算,数字的二进制位左移三位相当于乘以 2 的三次方。
为什么重写equals时必须重写hashcode方法
Object 的 hashcode 方法是本地方法,该方法直接返回对象的内存地址。如果没有重写hashCode(),则任何对象的hashCode()值都不相等。如果只重写equals没有重写hashCode(),就会导致相同的key值也被hashcode认为是不同的key值
5.为什么Java字符串是不可变的?有什么好处?
String 类被 final 关键字修饰,这就意味着没有子类可以重写它的方法。
String 类内部使用一个私有的字符数组来存储字符串数据。这个字符数组在创建字符串时被初始化,之后不允许被改变。
好处:
-保证 String 对象的安全性,避免被篡改;
-保证哈希值不会频繁变更。以哈希表的键值来说,经常变更的话,哈希表的性能会下降。在 String 类中,哈希值是在第一次计算时缓存的,后续对该哈希值的请求将直接使用缓存值;
-实现字符串常量池,Java 会将相同内容的字符串存储在字符串常量池中。这样,具有相同内容的字符串变量可以指向同一个 String 对象,节省内存空间。
6.Integer类的缓存机制
IntegerCache: Integer 类内部中内置了 256 个 Integer 类型的缓存数据,数据范围在 -128~127 之间。超过此范围,要比较Integer对象的数值是否相等,应该使用equals方法,而不是==运算符。
.
通过 Integer.valueOf() 方法获取整数对象时,会先检查该整数是否在 IntegerCache 中,如果在,则返回缓存中的对象,否则创建一个新的对象并缓存起来。
如果使用 new Integer() 创建对象,即使值在 -128 到 127 范围内,也不会被缓存,每次都会创建新的对象。【比如new Integer(10) == new Integer(10) :false】因此,推荐使用 Integer.valueOf() 方法获取整数对象。
.
相关补充:String 转成 Integer,主要有两个方法:Integer.parseInt(String s)、Integer.valueOf(String s)
7.异常
Throwable 是 Java 语言中所有错误和异常的基类。它有两个主要的子类:Error 和 Exception。
Error 类代表那些严重的错误,这类错误通常是程序无法处理的。比如,OutOfMemoryError 表示内存不足,StackOverflowError 表示栈溢出。这些错误通常与 JVM 的运行状态有关,一旦发生,应用程序通常无法恢复。
Exception 类代表程序可以处理的异常。它分为两大类:编译时异常 和 运行时异常。
编译时异常在编译时必须被显式处理(捕获或声明抛出),比如IOException、SQLException 等。
运行时异常在运行时抛出,通常是由程序逻辑错误导致的,如 NullPointerException、ArrayIndexOutOfBoundsException 等。
NoClassDefFoundError 和 ClassNotFoundException 有什么区别
它们都是由于系统运行时找不到要加载的类导致的,但是触发的原因不一样。
NoClassDefFoundError:当JVM在加载一个类的时候,这个类在编译时是可用的,但是在运行时找不到这个类的定义。原因可能是 jar 包缺失或者调用了初始化失败的类。
ClassNotFoundException:当应用程序运行的过程中尝试使用类加载器去加载Class文件的时候,没有在classpath中查找到指定的类。原因可能是要加载的类不存在或者类名写错了。
异常的处理主要有两种方式:抛出(throw,throws) 和捕获(try{} catch(){} finally{})
throw 和 throws 的区别
1)throws 关键字用于声明异常;而 throw 关键字用于显式的抛出异常。
2)throws 关键字后面跟的是异常的名字;而 throw 关键字后面跟的是异常的对象。
3)throws 关键字出现在方法签名上,而 throw 关键字出现在方法体里。
4)throws 关键字在声明异常的时候可以跟多个,用逗号隔开;而 throw 关键字每次只能抛出一个异常。
try 里的 return 先执行还是 finally 先执行?
finally 先执行。但是,在执行 finally 之前,JVM 会先将 return 的结果暂存起来,即使 finally 修改了 return 的变量值,返回值也不会改变。
8.BIO、NIO、AIO
BIO(Blocking I/O):阻塞 I/O,基于流模型。线程在执行 I/O 操作时被阻塞,无法处理其他任务,适用于连接数较少的场景。
NIO(New I/O 或 Non-blocking I/O):非阻塞 I/O ,基于通道和缓冲区。线程在等待 I/O 时可执行其他任务,适用于连接数多但连接时间短的场景。NIO 的魅力主要体现在网络编程中,服务器可以用一个线程处理多个客户端连接,通过 Selector 监听多个 Channel 来实现多路复用,极大地提高了网络编程的性能。
AIO(Asynchronous I/O):异步 I/O ,引入了异步通道的概念,基于事件和回调机制。线程发起 I/O 请求后立即返回,当 I/O 操作完成时通过回调函数通知线程,适用于连接数多且连接时间长的场景。
补充:既然有了字节流,为什么还要有字符流?
其实字符流是由 Java 虚拟机将字节转换得到的,问题就在于这个过程比较耗时,并且,如果我们不知道编码类型就很容易出现乱码问题。所以, I/O 流就干脆提供了一个直接操作字符的接口。
在计算机中,文本和视频都是按照字节存储的,只是如果是文本文件的话,我们可以通过字符流的形式去读取,这样更方面的我们进行直接处理。
9.序列化和反序列化
serialVersionUID 是标识类版本的唯一标识符,确保在序列化和反序列化过程中类的版本是兼容的;
Serializable接口用于标记一个类可以被序列化;
序列化只会保存对象的状态,因此不包含静态变量;
可以使用 transient 关键字修饰不想序列化的变量;
Java反射
反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。
反射的原理:Java 程序的执行分为编译和运行两步,编译之后会生成字节码(.class)文件,JVM 进行类加载的时候,会加载字节码文件,将类型相关的所有信息加载进方法区,反射就是去获取这些信息,然后进行各种操作。
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » Java 基础查漏补缺
发表评论 取消回复