Java面试中高频的几个容易混淆的概念解析

个人博客内容同步至公众号:第六范式
如有帮助欢迎关注,问题或建议,请公众号或博客留言。

Java中有些概念看似一字之差, 实则毫无联系。比如 final、finally 和 finalizeCollection 和 Collections。如果你要问我final、finally 和 finalize有什么区别?Collection 和 Collections有什么区别?那我只能说不是雷锋和雷峰塔的区别就是美人和美人鱼的区别。

本文总结了Java面试中高频的几个容易混淆的概念解析,皆是干活,放心食用😄

  1. final、finally 和 finalize有什么区别?
  2. Collection 和 Collections有什么区别?
  3. 重写和重载有什么区别?
  4. String,StringBuffer和StringBuilder有什么区别?
  5. ArrayList和LinkedList有什么区别?
  6. throw和throws有什么区别?
  7. sleep()和wait()有什么区别?

1. final、finally 和 finalize有什么区别?

final 是 Java 中的关键字,它也是 Java 中很重要的一个关键字,final 修饰的类、方法、变量有不同的含义;
finally 也是一个关键字,不过 finally 通常和其他关键字结合做一些组合操作;
finalize 是一个不让人待见的方法,它是对象祖宗 Object 中的一个方法,finalize 机制现在已经不推荐使用了。

1.1 final的使用细节
final 可以修饰类、属性、方法和局部变量.在某些情况下,程序员可能有以下需求,就会使用到 final :
1) 当不希望类被继承时,可以用 final 修饰
2) 当不希望父类的某个方法被子类覆盖/重写 (override) 时,可以用 final 关键字修饰
3)当不希望类的的某个属性的值被修改,可以用 final 修饰.
4)当不希望某个局部变量被修改,可以使用 final 修饰
final 使用注意事项:

  • final修饰的属性又叫常量,一般用 XX_XX_XX 来命名
  • final修饰的属性,在定义时必须赋初值,并且以后不能再修改,赋值可以在如下位置之一:①定义时:如 public final double TAX_RATE = 0.08;2)在构造器中;③在代码块中。
    3)如果final修饰的属性是静态static的,则初始化的位置只能是定义时或在静态代码块(不能在构造器中赋值)。
    4) final类不能继承,但是可以实例化对象。
    5)如果类不是final类,但是含有final方法,则该方法虽然不能重写,但是可以被继承。
    5)一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法。
    6) final不能修饰构造方法(即构造器)
    7) final和static往往搭配使用,效率更高,不会导致类加载(底层编译器做了优化处理)
    8)包装类(Integer,Double,Float, Boolean等都是final),String也是final类。
    9)final 修饰的引用类型,只是保证对象的引用不会改变。对象内部的数据可以改变。

1.2 finally的使用细节
finally 是保证程序一定执行的机制,同样的它也是 Java 中的一个关键字,一般来讲,finally 一般不会单独使用,它一般和 try 块一起使用,例如下面是一段 try...finally 代码块:

1try{
2  lock.lock();
3}finally {
4  lock.unlock();
5} 

这是一段加锁/解锁的代码示例,在 lock 加锁后,在 finally 中执行解锁操作,因为 finally 能够保证代码一定被执行,所以一般都会把一些比较重要的代码放在 finally 中,例如解锁操作流关闭操作连接释放操作等。

lock.lock() 产生异常时还可以和 try...catch...finally 一起使用:

1try{
2  lock.lock();
3}catch(Exception e){
4  e.printStackTrace();
5}finally {
6  lock.unlock();
7} 

其次,finally 块在 try 块执行完成后,或者 try 块未执行完成但是接下来是控制转移语句时(return/continue/break),finally 块在控制转移语句之前执行
对于 finally 的执行时机,我们以 return 为例来看一下是怎么回事。如下这段代码:

 1static int mayThrowException(){
 2  try{
 3    return 1;
 4  }finally {
 5    System.out.println("finally");
 6  }
 7}
 8
 9public static void main(String[] args) {
10  System.out.println(FinallyTest.mayThrowException());
11} 

从执行结果可以证明是 finally 要先于 return 执行的。

当 finally 有返回值时,会直接返回。不会再去返回 try 或者 catch 中的返回值。

 1static int mayThrowException(){
 2  try{
 3    return 1;
 4  }finally {
 5    return 2;
 6  }
 7}
 8
 9public static void main(String[] args) {
10  System.out.println(FinallyTest.mayThrowException());
11} 

在执行 finally 语句之前,控制转移语句会将返回值存在本地变量中。

 1static int mayThrowException(){
 2  int i = 100;
 3  try {
 4    return i;
 5  }finally {
 6    ++i;
 7  }
 8}
 9
10public static void main(String[] args) {
11  System.out.println(FinallyTest.mayThrowException());
12} 

上面这段代码能够说明 return i 是先于 ++i 执行的,而且 return i 会把 i 的值暂存,和 finally 一起返回。
finally 的本质:
下面我们来看一段代码:

 1public static void main(String[] args) {
 2
 3  int a1 = 0;
 4  try {
 5    a1 = 1;
 6  }catch (Exception e){
 7    a1 = 2;
 8  }finally {
 9    a1 = 3;
10  }
11
12  System.out.println(a1);
13} 

这段代码输出的结果是什么呢? 答案是 3,Why??? (○´・д・)ノ
抱着疑问,我们先来看一下这段代码的字节码:

<

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值