先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索【程序职场】关注这个执着的职场程序员。
我有什么:职场规划指导,技能提升方法,讲不完的职场故事,个人成长经验。
聚焦软件开发技能,项目管理,产品设计,运营,职业选择,规划
最近一直搞前后端分离框架,没有时间整理功能点的文章,所以最近文章更新不是太频繁。相信大家一定能理解我们这些苦逼程序员。
昨天的异常捕获文章,在看的时候突然发现,他们里面有一个 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(),产生问题。 所以,不推荐使用。
本文 Gitee https://gitee.com/dot_happydz/javaCode 已收录,欢迎 star。
我是【尔东双月】一枚执着的职场程序员,微信搜索【程序职场】关注我。别忘了三连啊,点赞、收藏、留言,随意给,我不挑。
知乎号: 程序职场
注:如果文章有任何问题,欢迎毫不留情地指正。