Java基础三
2021/6/19 17:32:07
本文主要是介绍Java基础三,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- Java中的Exception和Error有什么区别?
- JIT编译器
- Java中的值传递和引用传递可以解释下吗?
- 剩余java基础面试题
Java中的Exception和Error有什么区别?
- Exception是程序正常运行中预料到可能会出现的错误,并且应该被捕获并进行相应的处理,是一种异常现象
- Error是正常情况下不可能发生的错误,Error会导致JVM处于一种不可恢复的状态,不需要捕获处理,比如说OutOfMemoryError
Exception又分为了运行时异常和编译时异常。
-
编译时异常(受检异常)表示当前调用的方法体内部抛出了一个异常,所以编译器检测到这段代码在运行时可能会出异常,所以要求我们必须对异常进行相应的处理,可以捕获异常或者抛给上层调用方。
-
运行时异常(非受检异常)表示在运行时出现的异常,常见的运行时异常包括:空指针异常,数组越界异常,数字转换异常以及算术异常等。
-
异常Exception应该被捕获,使用try – catch – finally 来处理异常,并且使得程序恢复正常。
捕获异常应该遵循哪些原则呢
- 尽可能捕获比较详细的异常,而不是使用Exception一起捕获。
- 当本模块不知道捕获之后该怎么处理异常时,可以将其抛给上层模块。上层模块拥有更多的业务逻辑,可以进行更好的处理。
- 捕获异常后至少应该有日志记录,方便之后的排查。
- 不要使用一个很大的try – catch包住整段代码,不利于问题的排查。
不遵守这些原则的话,捕获到异常,却看不出是哪里抛出的!
一个容易混淆的异常与错误知识点
NoClassDefFoundError 和 ClassNotFoundException 有什么区别?
- 名字中,我们可以看出前者是一个错误,后者是一个异常。
- JDK中对ClassNotFoundException异常的阐述:当我们使用例如Class.forName方法来动态的加载该类的时候,传入了一个类名,但是其并没有在类路径中被找到的时候,就会ClassNotFoundException异常。出现这种情况,一般都是类名字传入有误导致的。
- JDK中对该错误NoClassDefFoundError的阐述:如果JVM或者ClassLoader实例尝试加载(可以通过正常的方法调用,也可能是使用new来创建新的对象)类的时候却找不到类的定义。但是要查找的类在编译的时候是存在的,运行的时候却找不到了。这个时候就会导致NoClassDefFoundError。出现这种情况,一般是由于打包的时候漏掉了部分类或者Jar包被篡改已经损坏。
JIT编译器
Java是一种先编译,后解释执行的语言。何为JIT编译器呢?
JIT编译器全名叫Just In Time Compile 也就是即时编译器,把经常运行的代码作为"热点代码"编译成与本地平台相关的机器码,并进行各种层次的优化。JIT编译除了具有缓存的功能外,还会对代码做各种优化,包括逃逸分析、锁消除、 锁膨胀、方法内联、空值检查消除、类型检测消除以及公共子表达式消除等。
逃逸分析
逃逸分析的基本行为就是分析对象动态作用域,当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他地方中,称为方法逃逸。
- 同布省略:也就是锁消除,当JIT编译器判断不会产生并发问题,那么会将同步synchronized去掉
- 标量替换
标量和聚合量的基本概念
- 标量(Scalar)是指一个无法再分解成更小的数据的数据。Java中的原始数据类型就是标量。
- 聚合量(Aggregate)是还可以分解的数据。Java中的对象就是聚合量,因为他可以分解成其他聚合量和标量。
在JIT阶段,如果经过逃逸分析,发现一个对象不会被外界访问的话,那么经过JIT优化,就会把这个对象拆解成若干个其中包含的若干个成员变量来代替。这个过程就是标量替换。标量替换的好处就是对象可以不在堆内存进行分配,为栈上分配提供了良好的基础。
逃逸分析缺点:技术不是特别成熟,分析的过程也很耗时,如果没有一个对象是不逃逸的,那么就没用了。
Java中的值传递和引用传递可以解释下吗?
- 值传递,意味着传递了对象的一个副本,即使副本被改变,也不会影响源对象。
- 引用传递,意味着传递的并不是实际的对象,而是对象的引用。因此,外部对引用对象的改变会反映到所有的对象上。
值传递案例
public class Test { public static void main(String[] args) { int x=0; change(x); System.out.println(x); } static void change(int i){ i=7; } }
上边的代码会输出0。因为如果参数是基本数据类型,那么是属于值传递的范畴,传递的其实是源对象的一个copy副本,不会影响源对象的值。
引用传递案例
public class Test { public static void main(String[] args) { StringBuffer x = new StringBuffer("Hello"); change(x); System.out.println(x); } static void change(StringBuffer i) { i.append(" world!"); } }
输出为Hello world!
变化一下
public class Test { public static void main(String[] args) { StringBuffer x = new StringBuffer("Hello"); change2(x); System.out.println(x); } static void change2(StringBuffer i) { i = new StringBuffer("hi"); i.append(" world!"); } }
再变化一下
public class Test { public static void main(String[] args) { StringBuffer sb = new StringBuffer("Hello "); System.out.println("Before change, sb = " + sb); changeData(sb); System.out.println("After change, sb = " + sb); } public static void changeData(StringBuffer strBuf) { StringBuffer sb2 = new StringBuffer("Hi,I am "); strBuf = sb2; sb2.append("World!"); } }
同样画内存图不难得到
剩余java基础面试题
- StringBuffer与StringBuilder的区别?
- Java中的泛型的理解
- Java序列化与反序列化的过程
- equals和hashCode方法的关系?
- Java和C++的区别有哪些?
- 静态与非静态的区别?
- Java中equals方法和==的区别?
这篇关于Java基础三的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南