java 的认识

Java特性

面向对象(封装,继承,多态)
平台无关性(JVM运行.class文件, 利用 jvm 屏蔽了硬件的区别)
语言(泛型,Lambda)
类库(集合,并发,网络,IO/NIO)
JRE(Java运行环境,JVM,类库)
JDK(Java开发工具,包括JRE,javac,诊断工具)

Java是解析运行吗?

  • 不是
  1. Java源代码经过Javac编译成.class文件
  2. .class文件经JVM解析或编译运行。
    • 解析:.class文件经过JVM内嵌的解析器解析执行。
    • 编译:存在JIT编译器(Just In Time Compile 即时编译器)把经常运行的代码作为热点

代码编译与本地平台相关的机器码,并进行各种层次的优化。

  • AOT编译器: Java 9提供的直接将所有代码编译成机器码执行。

error 和 exception 的区别,以及运行期异常和非运行期异常的区别

  1. error 和 exception 是 throwable 的子类,java 中只有 throwable 才可以 throw 或者 catch
  2. error 和 exception 体现了 java 设计者对异常情况的分类
    1. exception 表示是程序运行时可能出现的异常情况,它应该可以被 catch,且根据需要进行相应的处理
    2. error 表示程序运行时不应该出现的异常情况,绝大多数 error 会导致程序处于不正常、甚至无法运行的状态,不便也不应该进行 catch
  3. checked exception 和 unchecked exception
    1. checked exception 应该在程序中显式的进行捕获处理,是编译期检查的一部分。
    2. unchecked exception 是运行期异常,它是由于编码错误等出现逻辑错误导致的,它可以被 catch,并且根据业务的需要自行决定是否进行处理,不在编译期强制要求。 派生于 error 和 exception 中的 runtimeException 属于该 unchecked exception

NoClassDefFoundError 和 ClassNotFoundException 有什么区别

ClassNotFoundException NoClassDefFoundError
属于java.lang.Exception 的子类 属于 java.lang.Error 的子类
当程序动态加载 Class 的时候找不到类会抛出该异常 当编译成功以后,在程序执行过程中 Class 找不到导致抛出该错误
一般在执行 Class.forName(), ClassLoader.loadClass(), ClassLoader.findSystemClass() 的时候抛出 由 JVM 的运行期系统抛出

如何处理异常/有啥注意事项

  • 常见的是 try catch finally, 为了方便处理,java 引入了类似 try-with-resourcesmultiple catch
    • try-with-resources 适合于那些需要利用 finally 关闭资源的类,比如实现了 java.lang.AutoCloseable 或者 java.io.Closeable 的类
    • multiple catch 适合对 catch 到的多个异常进行统一处理时使用,利用 | 进行分割
  • throw earlycatch late
    • throw early 就是将可能出现异常的代码放在前面,跟进一步说,要对可能出现异常的代码先行进行诸如参数校验等操作,避免抛出异常
    • catch lage 捕获到的异常如果处理不了,应该抛出,让高层逻辑进行判断
  • try catch 会给 jvm 带来额外的开销
    • 建议捕获可能出现异常的代码,而不是捕获一大段代码
    • 不要用异常捕获机制来作为控制业务的流程
  • 别人的总结
    • 不要在finally代码块中处理返回值。
    • 按照我们程序员的惯性认知:当遇到return语句的时候,执行函数会立刻返回。但是,在Java语言中,如果存在finally就会有例外。除了return语句,try代码块中的break或continue语句也可能使控制权进入finally代码块。
    • 请勿在try代码块中调用return、break或continue语句。万一无法避免,一定要确保finally的存在不会改变函数的返回值。
    • 函数返回值有两种类型:值类型与对象引用。对于对象引用,要特别小心,如果在finally代码块中对函数返回的对象成员属性进行了修改,即使不在finally块中显式调用return语句,这个修改也会作用于返回值上。

final、finally、 finalize 有什么不同?

final

  • 根据场景不同,会有不同的作用
    • 作用在类上,表明该类不可被继承
    • 作用在方法上,表明该方法不能被重写
    • 作用在成员变量/局部变量上,表明该变量不可被修改
  • final 可以明确表示对代码的语义和逻辑,告诉别人不要修改
  • final 具有不能 immutable 的能力,但不完全是 immutable(不可变性)
    • 比如对集合变量用 final 修饰,仅仅表示该集合变量地址不能改变,但是并不能限制对它的元素操作

      拓展 如何实现 immutable 类

  1. final 修饰类
  2. 成员变量声明为 private 和 final,并且不能有 setter 方法
  3. 通常构造对象时,成员变量使用深度拷贝来初始化,而不是直接赋值,这是一种防御措施,因为你无法确定输入对象不被其他人修改。
  4. 如果确实需要实现 getter 方法,或者其他可能会返回内部状态的方法,使用 copy-on-write原则,创建私有的 copy。

finally

  • finally 是表明要保证某些代码必须被执行的机制
  • 可以使用 try-finally try-with-resources 进行资源的关闭

finalize

  • finalize 是基础类 java.lang.Object 的方法,目的是保证对象在被垃圾回收之前完成对资源的处理逻辑
    • 现在不推荐使用,在 jdk9 被设置为 Deprecated