范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

工作5年的程序员感慨finalfinallyfinalize面试这么卷?

  面试题:final、finally、finalize的区别面试考察点
  考察目的: 了解求职者对Java基础的了解。
  考察范围: 工作1-3年的Java程序员。背景知识
  final/finally在工作中几乎无时无刻不再使用,因此即便是没有系统化的梳理这个问题,也能回答出一些内容。
  但是finalize就接触得非常少,接下来我们对这几个关键字逐一进行分析。final关键字
  final关键字代表着不可变性。
  在面试题系列:工作5年,第一次这么清醒的理解final关键字?.这篇文章中, 我详细的进行了分析,建议大家去看这篇文章,这里就不重复分析了。finally关键字
  finally关键字用在try语句块后面,它的常用形式是try{  }catch(){  }finally{  }
  以及下面这种形式。try{  }finally{  }
  finally语句块中的代码,无论try或者catch代码块中是否有异常,finally语句块中的代码一定会被执行,所以它一般用于清理工作、关闭链接等类型的语句。
  它的特点:finally语句一定会伴随try语句出现。try语句不能单独使用,必须配合catch语句或finally语句。try语句可以单独与catch语句一起使用,也可以单独与finally语句一起使用,也可以三者一起使用。finally 实战思考
  为了加深大家对于finally关键字的理解,我们来看下面这段代码。
  思考一下,下面这段代码,打印的结果分别是多少?public class FinallyExample {      public static void main(String arg[]){         System.out.println(getNumber(0));         System.out.println(getNumber(1));         System.out.println(getNumber(2));         System.out.println(getNumber(4));     }     public static int getNumber(int num){         try{             int result=2/num;             return result;         }catch(Exception exception){             return 0;         }finally{             if(num==0){                 return -1;             }             if(num==1){                 return 1;             }         }     } }
  正确答案分别是:-1: 传入num=0,此时会报错java.lang.ArithmeticException: / by zero。因此进入到catch捕获该异常。由于finally语句块一定会被执行,因此进入到finally语句块,返回-1。1:传入num=1,此时程序运行正常,由于finally语句块一定会被执行,因此进入到finally代码块,得到结果1。1:传入num=2,此时程序运行正常,result=1,由于finally语句块一定会被执行,因此进入到finally代码块,但是finally语句块并没有触发对结果的修改,所以返回结果为1。0:传入num=4,此时程序运行正常,result=0(因为2/4=0.5,转换为int后得到0),由于finally语句块一定会被执行,因此进入到finally代码块,但是finally语句块并没有触发对结果的修改,所以返回结果为0。什么情况下finally不会执行
  finally代码块,是否有存在不会被执行的情况呢?System.exit()
  来看下面这段代码:public class FinallyExample {      public static void main(String arg[]){         System.out.println(getNumber(0));     }     public static int getNumber(int num){         try{             int result=2/num;             return result;         }catch(Exception exception){             System.out.println("触发异常执行");             System.exit(0);             return 0;         }finally{             System.out.println("执行finally语句块");         }     } }
  在catch语句块中,增加了System.exit(0)代码,执行结果如下触发异常执行
  可以发现,在这种情况下,并没有执行finally语句块。扩展知识,为什么System.exit(0)会破坏finally呢?
  来看一下源码以及注释。/**      * Terminates the currently running Java Virtual Machine. The      * argument serves as a status code; by convention, a nonzero status      * code indicates abnormal termination.      * 

* This method calls the exit method in class * Runtime. This method never returns normally. *   * The call System.exit(n) is effectively equivalent to * the call: * * Runtime.getRuntime().exit(n) * * * @param status exit status. * @throws SecurityException * if a security manager exists and its checkExit * method doesn"t allow exit with the specified status. * @see java.lang.Runtime#exit(int) */ public static void exit(int status) { Runtime.getRuntime().exit(status); }   该方法用来结束当前正在运行的Java JVM。如果 status 是非零参数,那么表示是非正常退出。   System.exit(0) : 将整个虚拟机里的内容都关掉,内存都释放掉!正常退出程序。   System.exit(1) : 非正常退出程序   System.exit(-1) :非正常退出程序   由于当前JVM已经结束了,因此程序代码自然不能继续执行。守护线程被中断   先来看下面这段代码:public class FinallyExample { public static void main(String[] args) { Thread t = new Thread(new Task()); t.setDaemon(true); //置为守护线程 t.start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { throw new RuntimeException("the "+Thread.currentThread().getName()+" has been interrupted",e); } } } class Task implements Runnable { @Override public void run() { System.out.println("执行 run()方法"); try { System.out.println("执行 try 语句块"); TimeUnit.SECONDS.sleep(5); //阻塞5s } catch(InterruptedException e) { System.out.println("执行 catch 语句块"); throw new RuntimeException("the "+Thread.currentThread().getName()+" has been interrupted",e); } finally { System.out.println("执行 finally 语句块"); } } }   运行结果如下:执行 run()方法 执行 try 语句块   从结果发现,finally语句块中的代码并没有被执行?为什么呢?守护线程的特性是:只要JVM中没有任何非守护线程在运行,那么虚拟机会kill掉所有守护线程从而终止程序。换句话说,就是守护线程是否正在运行,都不影响JVM的终止。   在虚拟机中,垃圾回收线程以及main线程都是守护线程。   在上述运行的程序中,执行逻辑描述如下:线程t是守护线程,它开启一个任务Task执行,该线程t在main方法中执行,并且在睡眠1s之后,main方法执行结束Task是一个守护线程的执行任务,该任务睡眠5s。   基于守护线程的特性,main和task都是守护线程,因此当main线程执行结束后,并不会因为Task这个线程还未执行结束而阻塞。而是在等待1s后,结束该进程。   这就使得Task这个线程的代码还未执行完成,但是JVM进程已结束,所以finally语句块没有被执行。finally执行顺序   基于上述内容的理解,是不是自认为对finally关键字掌握很好了?那我们在来看看下面这个问题。   这段代码的执行结果是多少呢?public class FinallyExample2 { public int add() { int x = 1; try { return ++x; } catch (Exception e) { System.out.println("执行catch语句块"); ++x; } finally { System.out.println("执行finally语句块"); ++x; } return x; } public static void main(String[] args) { FinallyExample2 t = new FinallyExample2(); int y = t.add(); System.out.println(y); } }   上述程序运行的结果是:2   这个结果应该有点意外,因为按照finally的语义,首先执行try代码块,++x后得到的结果应该是2, 接着再执行finally语句块,应该是在2的基础上再+1,得到结果是3,那为什么是2?   在解答这个问题之前,先来看一下这段代码的字节码,使用javap -v FinallyExample2. public int add(); descriptor: ()I flags: ACC_PUBLIC Code: stack=2, locals=4, args_size=1 0: iconst_1 //iconst 指令将常量压入栈中。 1: istore_1 // 2: iinc 1, 1 //执行++x操作 5: iload_1 6: istore_2 7: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 10: ldc #3 // String 执行finally语句块 12: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 15: iinc 1, 1 18: iload_2 19: ireturn 20: astore_2 21: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 24: ldc #6 // String 执行catch语句块 26: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 29: iinc 1, 1 32: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 35: ldc #3 // String 执行finally语句块 37: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 40: iinc 1, 1 43: goto 60 46: astore_3 47: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 50: ldc #3 // String 执行finally语句块 52: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 55: iinc 1, 1 58: aload_3 59: athrow 60: iload_1 61: ireturn Exception table: from to target type 2 7 20 Class java/lang/Exception 2 7 46 any 20 32 46 any   简单说明一下和本次案例分析有关的字节指令iconst,把常量压入到栈中。istore,栈顶的int数值存入局部变量表。iload,把int类型的变量压入到栈顶。iinc,对局部变量表中index为i的元素加上n。ireturn,返回一个int类型的值。astore,将一个数值从操作数栈存储到局部变量表。athrow,抛出一个异常。aload,将一个局部变量加载到操作栈。   了解了这些指令之后,再来分析上述字节码的内容。   先来看第一步分,这部分是try代码块中的指令。0: iconst_1 //iconst 指令将常量压入栈中。 1: istore_1 // 2: iinc 1, 1 //执行++x操作 5: iload_1 6: istore_2   上述指令的执行流程,图解如下。   接下来继续往下看字节码,这个是在finally里面执行的指令。15: iinc 1, 1 18: iload_2 19: ireturn 20: astore_2   从上述指令的图解过程中可以看到,在finally语句块中虽然对x的值做了累加,但是最终返回的时候,仍然是2.   后续剩余的指令,是异常表对应的执行指令,异常表的解读方式是:   从2行到第7行,如果触发了Exception,则会跳转到20行的指令开始执行。   从2行到第7行,如果触发了任何异常,则会跳转到46行开始执行。   从20行到第32行,如果触发了任何异常,则会跳转到46行开始执行。Exception table: from to target type 2 7 20 Class java/lang/Exception 2 7 46 any 20 32 46 any   结论:从上述字节指令的执行过程中可以发现,当try中带有return时,会先执行return前的代码,然后暂时保存需要return的信息,再执行finally中的代码,最后再通过return返回之前保存的信息。所以这里运行的结果是2,而不是3。   除此之外,还有其他的变体,比如:public class FinallyExample2 { public int add() { int x = 1; try { return ++x; } catch (Exception e) { System.out.println("执行catch语句块"); ++x; } finally { System.out.println("执行finally语句块"); ++x; return x; } } public static void main(String[] args) { FinallyExample2 t = new FinallyExample2(); int y = t.add(); System.out.println(y); } }   那,这段代码运行结果是多少呢?   打印结果如下:执行finally语句块 3   结论:当finally中有return的时候,try中的return会失效,在执行完finally的return之后,就不会再执行try中的return。不过不推荐在finally中写return,这会破坏程序的完整性,而且一旦finally里出现异常,会导致catch中的异常被覆盖。   关于这个部分说解释的内容,在JVM的中有Exceptions and finally解释。   If the try clause executes a return, the compiled code does the following:Saves the return value (if any) in a local variable.Executes a jsr to the code for the finally clause.Upon return from the finally clause, returns the value saved in the local variable.   简单翻译如下:   如果 try 语句里有 return,那么代码的行为如下:如果有返回值,就把返回值保存到局部变量中执行 jsr 指令跳到 finally 语句里执行执行完 finally 语句后,返回之前保存在局部变量表里的值finalize方法   finalize 方法定义在 Object 类中,其方法定义如下:protected void finalize() throws Throwable { }   当一个类在被回收期间,这个方法就可能会被调用到。   它有使用规则是:当对象不再被任何对象引用时,GC会调用该对象的finalize()方法finalize()是Object的方法,子类可以覆盖这个方法来做一些系统资源的释放或者数据的清理可以在finalize()让这个对象再次被引用,避免被GC回收;但是最常用的目的还是做cleanupJava不保证这个finalize()一定被执行;但是保证调用finalize的线程没有持有任何user-visible同步锁。在finalize里面抛出的异常会被忽略,同时方法终止。当finalize被调用之后,JVM会再一次检测这个对象是否能被存活的线程访问得到,如果不是,则清除该对象。也就是finalize只能被调用一次;也就是说,覆盖了finalize方法的对象需要经过两个GC周期才能被清除。问题回答   面试题:final、finally、finalize的区别   回答:   final用来修饰类、方法、属性,被final修饰的类,表示该类无法被继承,被final修饰的属性,表示该属性无法被修改,被final修饰的方法,表示该方法无法被重写   finally,它和try语句块组成一个完整的语法,表示一定会被执行的代码块,当然也有方式可以破坏它的执行特性通过System.exit守护线程的终止   finalize方法,是一个类被回收期间可能会被调用的方法。问题总结   一道面试题,要深挖下来,可以产生很多变体。   这篇文章不一定非常全面的涵盖了所有可能的情况,但是各位读者一定要注意,只有体系化的知识,才能创造价值   本篇文章出自"跟着Mic学架构"的原创作品,如需转载,请关注作者同名公众号联系。


关麓的老宅细雨蒙蒙,在旅游接待处等了很久,也不知冷雨何时休,何时了?时间不等人,只得在导游小妹的引领下,冒雨进村。沿一条小溪曲折前行,溪边房屋错落有致,雨水打湿灰白的墙体,给山村增添了些许厚羊肚菌祛湿汤今天我们来学习制作羊肚菌祛湿汤。羊肚菌能提高免疫力抑制肿瘤抗病毒等,具有益肠胃化痰理气补肾补脑提神等功效。莲子补脾止泻止带益肾涩精养心安神。芡实益肾固精补脾止泻除湿止带。虫草花抗癌2022AI药物研发的回顾与趋势2022年,AI药物研发是逐渐回归理性的一年,也是富有变化的一年,在追捧和质疑声中不断前进。近日,行业媒体BiopharmaTrend针对2022年AI药物研发行业做了深度的回顾,大S本人首次否认吸毒!心脏问题不能滥用药物,每月收赡养费23万近日,汪小菲和大S两家人的骂战终于告一段落,汪小菲本人在社交平台发文道歉,表示自己也是因为情绪不稳定才挑起了这一场轩然大波,接下来他会烧掉床垫,彻底翻篇,不再和大S进行互相攻击。随生病教会我的事连续生病五天,第六天的时候怀着忐忑的心情醒来,慢慢感受身体里的情绪,今天似乎没有无尽的尿意,腹部也不再隐隐作痛,带着一颗不可思议的心情起床,从卧室走到卫生间,再从卫生间到厨房,最后轻狂是放纵1我很喜欢你,不是天天挂在嘴上的那种喜欢,是放在心里想都不敢想的那种喜欢。2既要今朝醉,也要万年长3我有一个秘密。我以为我永远都不会告诉你。我很喜欢你啊,寇忱。4希望我们的友谊不惧让生活多一点松弛感陶渊明有诗曰结庐在人境,而无车马喧。问君何能尔,心远地自偏。热闹的人世间,喧嚣的红尘里,要想达到如此境界,就要好好地修炼这一颗心。不管处在什么样的境遇之中,都不要把自己的弦绷得太紧情感文案,生活不会辜负用心的人最近很多人问我,我最近过得怎么样?我是一个平凡的人,没有什么特别,也不会有特别的事情。我对生活没什么要求,每天过得都很好。我做什么事情都没有什么要求,我有自己。我只是在努力地做着我粗粮与细粮的区别?别瞎选别瞎吃,一文教你冬季正确吃粮如何正确地吃粗粮五谷杂粮今年冬天疫情再次席卷而来,面对每天的新闻报道,嗅觉敏锐的人们早已养成了囤粮的习惯,几乎人人都在囤日常蔬菜瓜果,粮米油盐,俗话说手中有粮,心中不慌。一般不少人如何正确的搏命沙特给阿根廷上了一课全世界都在期待着梅西在世界杯的最后一舞,而从纸面上看,沙特是阿根廷最合适的对手这支世预赛上能客场1比1被国足逼平,历史上经常奉献惨案的软脚虾,谁敢猜他们能首战爆冷?沙特是靠运气拿下思念成殇,烟入骨髓已经不知道多少次,在想你泛滥成灾漆黑的夜里,燃起的香烟忽明忽暗缭绕散发着思念的光芒。嘴里鼻管里呼出的烟雾在手指间虚无缥缈聚集又慢慢地消散,留在口腔里苦涩的因子浓浓刺激着味蕾,如同你
iphone14发布时间,确定了!还有新AirPods苹果终于确定了iphone14号的新品发布时间,将于9月13日(星期二)在苹果秋季新品发布会上发布。关于iphone14的细节配置等早就不是秘密了。本次发布会最抢眼的iphone1如果太阳熄灭了,人类要多长时间才能感知到?8分钟?可能要1万年综述众所周知,太阳是给地球提供光照和热辐射的源头。按照太阳与地球之间的距离计算,太阳发出的光需要跑8分钟才能到达地球。换言之,如果太阳停止发光了,那么地球上的人类需要经过8分钟后才为证明时间不存在,科学家让一女性在洞穴住了130天,结果怎样?你对时间的定义是怎样的?相信在每一个人的心目中,对时间的定义都是不一样的。而时间是看不见,也摸不着的,属于一种缥缈的物质。有些科学家认为时间是不存在的,它只是被规定在了时间这一定义光速飞行,时间静止,人还会感觉到饿吗?爱因斯坦的狭义相对论彻底改变了人类对时空的传统认知,它告诉我们,时空并不是绝对不变的,而是相对的。狭义相对论中有一个著名的效应时间膨胀效应(钟慢效应),强调速度越快,时间就越慢。不入伏,这道碱性菜要多吃,营养高,清肠胃,好吃不上火人间烟火,最抚人心,便是那简单的一日三餐大家好,我是晓苹,每天分享生活中美食,让爱走进厨房,让家充满爱。入伏,这道碱性菜要多吃,营养高,清肠胃,好吃不上火!我喜欢夏季,大概是因为夏饺子馅能不能放蚝油?牢记2放4不放,饺子鲜嫩多汁,味道喷香饺子馅能不能放蚝油?牢记2放4不放,饺子鲜嫩多汁,味道喷香俗话说众口难调,但有一种食物,不分性别,无论年龄,大家都爱吃,它就是饺子。逢年过节,家家户户都会包饺子吃,寓意团圆吉祥。饺做肉丸子,放料太多难怪不好吃,只需2味料,口感弹牙味道香很多人在家都做过肉丸子,但是无论怎么做都是无法和买来的肉丸子相比,首先自己在家做的肉丸子不容易成型,一煮就很容易散,还有人虽然丸子做的成型了,但是口感却一点也不q弹,甚至还有些人做小龙女李若彤越老越有味道,黑色蕾丝西装美出新高度,牛奶肌惹眼李若彤越老越有味道,黑色蕾丝西装美出新高度,牛奶肌惹眼李若彤越老越有味道,黑色蕾丝西装美出新高度,牛奶肌惹眼李若彤越老越有味道,黑色蕾丝西装美出新高度,牛奶肌惹眼李若彤越老越有味道中国的四大古镇是哪些地方?咱们中国地大物博,也有很多好玩的地方,有很多旅游景点。中国的历史也是有上下5000年。有很多文化。还有很多文化小镇。千年古镇等等。那咱们中国的四大古镇是哪些地方呢?中国的四大古镇一一脚踏三省,景色不输乌镇,一个隐居千年的传奇古镇来源打望旅友不知从什么时候开始,热爱旅行的我们已经厌倦了从众打卡热闹喧嚣,更向往这样的地方一棵古树,一个小镇,一个人物,一段历史青木川,就是如此。青木川,一个很美而又饱含诗意的名字入伏,这道碱性菜要多吃,营养高,清肠胃,好吃不上火人间烟火,最抚人心,便是那简单的一日三餐大家好,我是晓苹,每天分享生活中美食,让爱走进厨房,让家充满爱。入伏,这道碱性菜要多吃,营养高,清肠胃,好吃不上火!我喜欢夏季,大概是因为夏