作者:jtzhn_146_607 | 来源:互联网 | 2023-09-08 23:11
1. final final意味着“最后的、最终的”含义,final可以用来修饰类,方法和变量(成员变量或局部变量)。
1.1 修饰类 当用final修饰类时,表明该类不能被其他类所继承。String是一个典型的final类型的类。
注意:final类中所有的成员方法都会隐式的定义为final方法。
1.2 修饰方法 把方法锁定,以防止继承类对其进行更改。如:枚举类中的equals()/clone() 此方法不能被重写,也不能在子类中重新定义同名同参的新方法
1.3 修饰变量 final成员变量表示常量,只能被赋值一次,赋值后其值不再改变。 当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化; 如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的,即地址的值不发生变化。 final修饰一个成员变量(属性),必须要显示初始化。这里有三种初始化方式,一种是在变量声明的时候初始化;第二种方法是在代码块中赋值;第三种方法是在构造函数中对这个变量赋初值。 final修饰一个方法形参,一旦调用该方法(传入了实参),该参数值就不能再修改。
2. finally finally是在处理异常时搭配try/catch语句使用,并且附带一个语句块,在服务正常运行的情况下finally语句块最终一定会被执行(不管有没有抛出异常),经常被用于释放资源。
注意:只有与finally对应的try语句块得到执行的情况下,finally语句块才一定会执行。
&#64;Test public void test ( ) { List < String > list &#61; Arrays . asList ( "123" , "12345" , "1234" , "4321" , "1234567" , "5678" ) ; try { list. forEach ( s -> { if ( s. length ( ) > 5 ) { throw new RuntimeException ( "foreach跳出循环" ) ; } System . out. println ( s) ; } ) ; } catch ( Exception e) { System . out. println ( "捕获异常" &#43; e. getMessage ( ) ) ; } finally { System . out. println ( "finally语句块执行&#xff01;&#xff01;&#xff01;" ) ; } }
当一个线程在执行 try 语句块或者 catch 语句块时被打断&#xff08;interrupted&#xff09;或者被终止&#xff08;killed&#xff09;&#xff0c;与其相对应的 finally 语句块可能不会执行。 如果finally中有return语句,&#xff0c;且已经执行到了try代码块&#xff0c;则不会执行try/catch中的return语句&#xff1b;如果finally中没有return&#xff0c;则执行完finally块中的代码&#xff0c;再执行try/catch中的return语句。
public static void main ( String [ ] args) { String s &#61; testFinallyReturn ( ) ; System . out. println ( s) ; } public static String testFinallyReturn ( ) { List < String > list &#61; Arrays . asList ( "123" , "12345" , "1234" , "4321" , "1234567" , "5678" ) ; try { list. forEach ( s -> { if ( s. length ( ) > 5 ) { throw new RuntimeException ( "foreach跳出循环" ) ; } System . out. println ( s) ; } ) ; return "成功" ; } catch ( Exception e) { System . out. println ( e. getMessage ( ) ) ; return "异常" ; } finally { System . out. println ( "finally语句块执行&#xff01;&#xff01;&#xff01;" ) ; } }
3. finalize finalize()是在java.lang.Object里定义的&#xff0c;也就是说每一个对象都有这么个方法。这个方法在gc启动&#xff0c;该对象被回收的时候被调用。其实gc可以回收大部分的对象&#xff08;凡是new出来的对象&#xff0c;gc都能搞定&#xff0c;一般情况下我们又不会用new以外的方式去创建对象&#xff09;&#xff0c;反射方式可以创建对象&#xff0c;所以一般是不需要程序员去实现finalize的。 特殊情况下&#xff0c;需要程序员实现finalize&#xff0c;当对象被回收的时候释放一些资源&#xff0c;比如&#xff1a;一个socket链接&#xff0c;在对象初始化时创建&#xff0c;整个生命周期内有效&#xff0c;那么就需要实现finalize&#xff0c;关闭这个链接。 使用finalize还需要注意一个事&#xff0c;调用super.finalize(); 一个对象的finalize()方法只会被调用一次&#xff0c;而且finalize()被调用不意味着gc会立即回收该对象&#xff0c;所以有可能调用finalize()后&#xff0c;该对象又不需要被回收了&#xff0c;然后到了真正要被回收的时候&#xff0c;因为前面调用过一次&#xff0c;所以不会再调用finalize()&#xff0c;进而产生问题。 所以&#xff0c;不推荐手动调用finalize()方法
&#xff0c;它跟析构函数不一样。