聚焦软件开发技能,项目管理,产品设计,运营,职业选择,规划

 

 

 

最近一直搞前后端分离框架,没有时间整理功能点的文章,所以最近文章更新不是太频繁。相信大家一定能理解我们这些苦逼程序员。

昨天的异常捕获文章,在看的时候突然发现,他们里面有一个 finally 处理,就想起了这几种对比,今天就简单的聊聊。

 

final,finally,finalize的区别

 

final用于声明属性变量,方法和类,分别表示属性不可交变,方法不可覆盖,类不可继承。        

finally是异常处理语句结构的一部分,表示总是执行。        

finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收,例如关闭文件等。

 

独立概念其实还是不太能理解,为了能更直观,当然是代码最直观,有代码有结果,你不说好都不行。下面我们就一一来说一下。

 

final

 

上面再说概念的时候 final 是用于声明属性变量,方法,类。这三种,我们来通过实例看分别怎么使用的?

1,属性变量

  •  
package com.company;
public class Main { public final String nameA = "程序职场"; //在定义时初始化 public final String nameB;{nameB="程序职场";} //在初始化块中初始化 public static final String nameC = "程序职场";//静态常量,在定义时初始化 public static final String nameD;static{nameD = "程序职场";}//静态常量,在静态初始化块中初始化 public final String nameE;//静态变量不能在初始化块中初始化,在函数中初始化 public Main() { nameE = "程序职场"; }
public static void main(String[] args) { // write your code here }}

2,方法
使用final 把方法锁定,以防止继承类对其进行更改,子类可以继承。
注意:若父类中final方法的访问权限为private,将导致子类中不能直接继承该方法,因此,此时可以在子类中定义相同方法名的函数,此时不会与重写final的矛盾,而是在子类中重新地定义了新方法。

  •  
package com.company;
public class style { public class ParentClass{ public final void TestFinal(){ System.out.println("父类--这是一个final方法---程序职场"); } } public class childClass extends ParentClass{ public void main(String[]args){ childClass sc = new childClass(); sc.TestFinal(); } }
public static void main(String[] args) {
}}

 

3,类

当用final修饰类的时,表明该类不能被其他类所继承。当我们需要让一个类永远不被继承,此时就可以用final修饰,但要注意:

final类中所有的成员方法都会隐式的定义为final方法。

  •  
package com.company;
public final class TestClass { String nameA = "程序职场"; final String nameB = "公众号"; public static void main(String[] args){ TestClass ft = new TestClass(); ft.nameA = "公众号:程序职场"; /*final类TestClass的属性值 i是可以改变的,因为属性值i前面没final修饰*/ System.out.println(ft.nameA); }}

比如设置如下的属性是错误的:
ft.nameB=”程序职场公众号“;//报错....因为j属性是final的不可以改变。

 

 

finally


昨天的文章我们说到了finally 语句块,主要是处理异常的时候用到。
那么他的作用是什么呢?

finally作为异常处理的一部分,它只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定会被执行(不管有没有抛出异常),经常被用在需要释放资源的情况下(例如:线程,数据库,数据流,文件流等等)

我们先搞一个小案例看看是不是每次都走finally:

  •  
package com.company;
public class Finally { public static void main(String[] args) { try{ throw new NullPointerException(); }catch(NullPointerException e){ System.out.println("程序抛出了异常"); }finally{ //这里总会被执行,线程,数据库,数据流,文件流等结束处理一般写在这里,可以降低程序的出错几率 System.out.println("执行了finally语句块"); } }}

输出结果:

程序抛出了异常

执行了finally语句块

从输出结果可以看出确实是都了,但是真的是什么情况下都要走吗?不一定,我就来举几个例子,虽然不一定用到,但是还是需要知道这种情况的。

  •  
try{    System.out.println("return 程序职场");    return;} catch (Exception e) {    e.printStackTrace();} finally {    System.out.println("return 是否 执行了finally语句");}

try { System.out.println("System.exit 程序职场"); System.exit(0);} catch (Exception e) { e.printStackTrace();} finally { System.out.println("System.exit情况下 是否 执行了finally语句");}

分别打印return 程序职场return 是否 执行了finally语句



System.out.println("System.exit 程序职场");

 

finalize
finalize()是在java.lang.Object里定义的,也就是说每一个对象都有这个方法。这个方法在gc启动,该对象被回收的时候被调用。其实gc可以回收大部分的对象(凡是new出来的对象,gc都能搞定,一般情况下我们又不会用new以外的方式去创建对象),所以一般是不需要去实现finalize的。 

 

特殊情况下,需要实现finalize,当对象被回收的时候释放一些资源,比如:一个socket链接,在对象初始化时创建,整个生命周期内有效,那么就需要实现finalize,关闭这个链接。 
使用finalize还需要注意一个事,调用super.finalize();
  一个对象的finalize()方法只会被调用一次,而且finalize()被调用不意味着gc会立即回收该对象,所以有可能调用finalize()后,该对象又不需要被回收了,然后到了真正要被回收的时候,因为前面调用过一次,所以不会调用finalize(),产生问题。 所以,不推荐使用。看到final,finally,finalize有多少程序员不淡定了?_数据库