final、finally与finalize的区别
1. final
在java中,final可以用来修饰类,方法和变量(成员变量或局部变量)。下面将对其详细介绍。
1.1 修饰类
当用final修饰类的时,表明该类不能被其他类所继承。当我们需要让一个类永远不被继承,此时就可以用final修饰,但要注意:
final类中所有的成员方法都会隐式的定义为final方法。
1.2 修饰方法
使用final方法的原因主要有两个:
(1) 把方法锁定,以防止继承类对其进行更改。
(2) 效率,在早期的java版本中,会将final方法转为内嵌调用。但若方法过于庞大,可能在性能上不会有多大提升。因此在最近版本中,不需要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");
}
}
1.3 修饰变量
final成员变量表示常量,只能被赋值一次,赋值后其值不再改变。类似于C++中的const。
当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。本质上是一回事,因为引用的值是一个地址,final要求值,即地址的值不发生变化。
final修饰一个成员变量(属性),必须要显示初始化。这里有两种初始化方式,一种是在变量声明的时候初始化;第二种方法是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有的构造函数中对这个变量赋初值。
当函数的参数类型声明为final时,说明该参数是只读型的。即你可以读取使用该参数,但是无法改变该参数的值。
在java中,String被设计成final类,那为什么平时使用时,String的值可以被改变呢?
字符串常量池是java堆内存中一个特殊的存储区域,当我们建立一个String对象时,假设常量池不存在该字符串,则创建一个,若存在则直接引用已经存在的字符串。当我们对String对象值改变的时候,例如 String a="A"; a="B" 。a是String对象的一个引用(我们这里所说的String对象其实是指字符串常量),当a=“B”执行时,并不是原本String对象("A")发生改变,而是创建一个新的对象("B"),令a引用它。
2. finally
finally作为异常处理的一部分,它只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定会被执行(不管有没有抛出异常),经常被用在需要释放资源的情况下。(×)(这句话其实存在一定的问题)
很多人都认为finally语句块一定会执行,但真的是这样么?答案是否定的,例如下面这个例子:

当我们去掉注释的三行语句,执行结果为:

为什么在以上两种情况下都没有执行finally语句呢,说明什么问题?
只有与finally对应的try语句块得到执行的情况下,finally语句块才会执行。以上两种情况在执行try语句块之前已经返回或抛出异常,所以try对应的finally语句并没有执行。
但是,在某些情况下,即使try语句执行了,finally语句也不一定执行。例如以下情况:

finally 语句块还是没有执行,为什么呢?因为我们在 try 语句块中执行了 System.exit (0) 语句,终止了 Java 虚拟机的运行。那有人说了,在一般的 Java 应用中基本上是不会调用这个 System.exit(0) 方法的。OK !没有问题,我们不调用 System.exit(0) 这个方法,那么 finally 语句块就一定会执行吗?
再一次让大家失望了,答案还是否定的。当一个线程在执行 try 语句块或者 catch 语句块时被打断(interrupted)或者被终止(killed),与其相对应的 finally 语句块可能不会执行。还有更极端的情况,就是在线程运行 try 语句块或者 catch 语句块时,突然死机或者断电,finally 语句块肯定不会执行了。可能有人认为死机、断电这些理由有些强词夺理,没有关系,我们只是为了说明这个问题。
易错点
在try-catch-finally语句中执行return语句。我们看如下代码:

答案:4,4,4 。 为什么呢?
首先finally语句在改代码中一定会执行,从运行结果来看,每次return的结果都是4(即finally语句),仿佛其他return语句被屏蔽掉了。
事实也确实如此,因为finally用法特殊,所以会撤销之前的return语句,继续执行最后的finally块中的代码。
3. finalize
finalize()是在java.lang.Object里定义的,也就是说每一个对象都有这么个方法。这个方法在gc启动,该对象被回收的时候被调用。其实gc可以回收大部分的对象(凡是new出来的对象,gc都能搞定,一般情况下我们又不会用new以外的方式去创建对象),所以一般是不需要程序员去实现finalize的。
特殊情况下,需要程序员实现finalize,当对象被回收的时候释放一些资源,比如:一个socket链接,在对象初始化时创建,整个生命周期内有效,那么就需要实现finalize,关闭这个链接。
使用finalize还需要注意一个事,调用super.finalize();
一个对象的finalize()方法只会被调用一次,而且finalize()被调用不意味着gc会立即回收该对象,所以有可能调用finalize()后,该对象又不需要被回收了,然后到了真正要被回收的时候,因为前面调用过一次,所以不会调用finalize(),产生问题。 所以,推荐不要使用finalize()方法,它跟析构函数不一样。
final、finally与finalize的区别的更多相关文章
- 异常-面试题之final,finally和finalize的区别,如果在finally之前有return
package cn.itcast_07; /* * 面试题: * 1:final,finally和finalize的区别 * final:最终的意思,可以修饰类,成员变量,成员方法 * 修饰类,类不 ...
- final,finally和finalize的区别
package com.heima.test; public class Test1 { /** * * A:面试题1 * final,finally和finalize的区别 * fina ...
- final, finally 和finalize的区别
final 修饰符(关键字) 如果一个类被声明为final,意味着它不能再派生新的子类,不能作为父类被继承.因此一个类不能及被声明为abstract,又被声明为final的.将变量或方法声明为fina ...
- java中final,finally和finalize的区别
final,finally和finalize的区别: final:最终的意思,可以修饰类,成员变量,成员方法 修饰类,类不能被继承 修饰变量,变量是常量 修饰方法,方法不能被重写 finally:是异 ...
- final、finally和finalize的区别
final.finally和finalize的区别 这三者的区别可以从两个方面来说 1.意思解释方面 (1)final是修饰符(关键字) (2)finally是异常处理中的程序块 (3)finaliz ...
- 【Java面试题】19 final,finally和finalize的区别
总体区别 final 用于申明属性,方法和类,表示属性不可变,方法不可以被覆盖,类不可以被继承.finally 是异常处理语句结构中,表示总是执行的部分. finallize ...
- Java基础知识总结--final、finally、finalize的区别
谈谈final.finally.finalize的区别 1.final修饰符:如果一个类被声明为final,意味着这个类不能再被派生出新的子类,不能作为父类被别的类继承.因此,一个类不能即被声明为ab ...
- Android源码中final关键字的用法及final,finally,finalize的区别
Android开发的学习流程 final,finally,finalize的区别 Android的发展越来越快,Android开发人员越来越多,当两种情况碰撞,在诸多开发者中跟紧Android步伐脱颖 ...
- 【Java面试题系列】:Java中final finally finalize的区别
本篇为[Java面试题系列]第三篇,文中如有错误,欢迎指正. 第一篇链接:[Java面试题系列]:Java基础知识常见面试题汇总 第一篇 第二篇链接:[Java面试题系列]:Java基础知识常见面试题 ...
- Java中final,finally和finalize区别
Day11_SHJavaTraing_4-18-2017 Java中final,finally和finalize区别 1.final—修饰符(关键字) ①final修饰类,表示该类不可被继承 ②fin ...
随机推荐
- phalcon环境的搭建和dll扩展下载与选择
phalcon需要下载一个扩展的dll文件才能运行项目 其中需要注意dll放在一个php扩展目录中windows下php/ext/,还需要在两个Php.ini文件中增加扩展说明,一般只需要更改 D:\ ...
- LeetCode & Q26-Remove Duplicates from Sorted Array-Easy
Descriptions: Given a sorted array, remove the duplicates in place such that each element appear onl ...
- Spring Boot整合Spring Security
Spring Boot对于该家族的框架支持良好,但是当中本人作为小白配置还是有一点点的小问题,这里分享一下.这个项目是使用之前发布的Spring Boot会员管理系统重新改装,将之前filter登录验 ...
- Java Jar包压缩、解压使用指南
什么是jar包 JAR(Java Archive)是Java的归档文件,它是一种与平台无关的文件格式,它允许将许多文件组合成一个压缩文件. 如何打/解包 使用jdk/bin/jar.exe工具,配置完 ...
- redis入门(05)redis的key命令
一.什么是redis键命令 Redis 键(key):Redis 键命令用于管理 redis 的键. Redis 键命令的基本语法: redis 127.0.0.1:6379> COMMAND ...
- android studio 何如修改报名
1. 重命名办法,网上很多见 2. 对于需要重新修改包名的级别的 a. 修改package 和 gradle 的包名,对应一致. b. 修改R 所在包名,使用crtl+n修改R文件的路径 c. 手动首 ...
- 高级控件 popwindow 与gridview的组合应用
Gridview 的布局设置 <GridView android:layout_width="wrap_content" android:layout_height=&quo ...
- nohup 与 & 的区别
nohup -- invoke a utility immune to hangups : 运行命令忽略挂起信号 & 是指后台运行: nohup 的功能和& 之间的功能并不相同.其中, ...
- [洛谷P3383][模板]线性筛素数-欧拉筛法
Description 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) Input&Output Input 第一行包含两个正整数N.M,分别表示查询的 ...
- C/C++下调用matlab函数操作说明
1.matlab的安装 连接:http://pan.baidu.com/s/1qXuF7aO 安装32位版本的matlab(在目录下bin文件夹中有两个文件夹,选择win32文件夹下的setup进行安 ...