final、finally 和 finalize

一、final 的三种用法

1️⃣如果一个类被声明为 final,意味着它不能再派生出新的子类,即不能被继承,因此它和 abstract 是反义词。想要让一个类永远不被继承,就可以用 final 修饰,但要注意:final 类中所有的成员方法都会隐式的定义为 final 方法。

2️⃣将变量声明为 final,可以保证它们在使用中不被改变,被声明为 final 的变量必须在声明时给定初值,在以后的引用中只能读取不可修改。

  1. 当 final 修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化。
  2. 当 final 修饰一个引用类型时,则在初始化之后便不能再让其指向其它对象了,但该引用所指向的对象的内容是可以发生变化的。本质上是一回事,因为引用的值是一个地址,final 要求该值,即地址的值不发生变化。
  3. final 修饰一个成员变量(属性),必须要显示初始化。这里有两种初始化方式,一种是在变量声明的时候初始化;第二种方法是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有的构造函数中对这个变量赋初值。
  4. 当函数的参数类型声明为 final 时,说明该参数是只读型的,无法改变该参数的值。
    注意:
    Java 中,String 被设计成 final,平时使用时,为什么可以改变 String 的值?
    字符串常量池是 Java 堆内存中一个特殊的存储区域。当建立一个 String 对象时,假设常量池不存在该字符串,则创建一个,若存在则直接引用已经存在的字符串。当改变 String 对象值的时候,例如String a = "A"; a = "B";,a 是 String 对象的一个引用(这里所说的 String 对象其实是指字符串常量),当执行 a = "B" 时,并不是原本 String 对象(“A”)发生改变,而是创建了一个新的对象(“B”),令 a 引用它。

3️⃣被声明为 final 的方法也同样只能使用,不能在子类中被重写。使用 final 方法的原因主要有两个:

  1. 把方法锁定,以防止继承类对其进行更改。
  2. 效率。在早期Java版本中,会将 final 方法转为内嵌调用。但若方法过于庞大,可能在性能上不会有多大提升。因此在最近版本中,不需要 final 方法进行这些优化了。

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

class A{
  private final void getName(){}
}
public class B extends A{
  public void getName(){}
  public static void main(String[]args){
     System.out.println("OK");
  }
}

二、finally

finally 作为异常处理的一部分,它只能用在 try/catch 语句中,并且附带一个语句块,表示这段语句最终一定会被执行(不管有没有抛出异常,只要 JVM 不关闭,与 finally 对应的 try 语句块得到执行的情况下,都能执行)。经常被用在需要释放外部资源的情况下。

finally 语句块没有执行的情况:

  1. 在 try 块中,发生异常代码前执行 System.exit(0) 语句,终止 JVM 的运行。
  2. 发生异常后,在 catch 块中执行 System.exit(0) 语句,终止 JVM 的运行。
  3. 当一个线程在执行 try 块或者 catch 块时被打断(interrupted)或者被终止(killed),与其相对应的 finally 块可能不会执行。
  4. 极端情况,就是在线程运行 try 块或者 catch 块时,突然死机或者断电,finally 块肯定不会执行了。

三、finalize

finalize() 是在java.lang.Object里定义的,也就是说每个对象都有该方法。Java 中允许使用 finalize() 在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销毁对象时调用的,通过重写 finalize() 可以整理系统资源或者执行其他清理工作。这个方法在 GC 启动,该对象被回收的时候被调用。其实 GC 可以回收大部分的对象(凡是 new 出来的对象,都能搞定,一般情况下又不会用 new 以外的方式去创建对象),所以一般不需要重写 finalize()。特殊情况,当对象被回收的时候释放一些资源,比如:一个 socket 链接,在对象初始化时创建,整个生命周期内有效,那么就需要重写 finalize,关闭这个链接。
使用 finalize 还需要注意一个事,调用 super.finalize();
一个对象的 finalize() 只会被调用一次,而且 finalize() 被调用不意味着 GC 会立即回收该对象。有可能调用 finalize() 后,该对象又不需要被回收了,然后到了真正要被回收的时候,因为前面调用过一次,所以不会调用 finalize(),产生问题。 所以,不推荐使用 finalize(),它跟析构函数不一样。

四、面试

  1. int x 被修饰成 final,意味着 x 不能在 addOne() 中被修改。所以编译报错。
  2. 判断

@Data
public class Tba {
  private int a;
}
public class Wg {
    public static void main(String[] args) {
        Tba tba = new Tba();
        System.out.println(new Wg().addOne(tba));
    }
    public int addOne(final Tba tba) {
        int a = tba.getA();
        return ++a;
    }
}

答案: 正确。在 addOne() 中,参数 tba 被修饰成 final。如果在 addOne() 里修改了 tba 的引用(tba = new Tba();),那么如同上例这题也是错的。但这里修改的是 tba 的 member vairable(成员变量),而 tba 的 reference 并没有改变。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,113评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,644评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,340评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,449评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,445评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,166评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,442评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,105评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,601评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,066评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,161评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,792评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,351评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,352评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,584评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,618评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,916评论 2 344

推荐阅读更多精彩内容

  • 桑椹 在厦门开会培训两天,一直窝在宾馆,脚...
    竹子的爸爸阅读 450评论 0 1
  • 千里单骑绝尘去, 朝辞晓风暮雨还。 此去征途何时尽? 一程风雨一程山。 这是我半生蹉跎的真实写照。每当自己独力面对...
    原疯不动阅读 706评论 7 12
  • 中央图是整个思维导图的核心,反映整个思维导图的主,它的非常多彩直接影响事个图的效果,中央图要求使用三种以上的...
    以缠证道阅读 1,035评论 0 0
  • 感覺自己放了幾天沒寫。 做了一些些決定,一些可能性的覺得。 我總記得老王說過,不管你怎麽樣我都會等你的,但是差點感...
    南瓜阿南阅读 114评论 0 0