在 java 中,final 可以用来修饰类,方法和变量(成员变量或局部变量)。
下面将对其详细介绍。
如果一个类被声明为final,就意味着它不能再派生出新的子类,不能作为父类被继承。因此:
注意:
final 类中所有的成员方法都会隐式的定义为 final 方法。
final 方法意味着“最后的、最终的”含义,即被声明 final 的方法只能使用,不能重载。
使用 final 方法的原因主要有两个:
demo 示例:
class A{
private final void getName(){
System.out.println("A.getName()...");
}
}
class B extends A{
public void getName(){
System.out.println("B.getName()...");
}
public static void main(String[]args){
B b = new B();
b.getName();
}
}
B.getName()...
final 成员变量表示常量,只能被赋值一次,赋值后其值不再改变。
final 修饰成员变量时,必须要显示初始化。这里有两种初始化方式:一种是在变量声明的时候初始化;第二种方法是在这个变量所在的类的所有的构造函数中对这个变量赋初值。
如果将变量或者方法声明为 final,可以保证它们在使用中不被改变。在并发编程中,将公共变量设置为 final 是最简单的并发安全实现方法。
finally 是对 Java 异常处理模型的最佳补充。finally 结构使代码总会执行,而不管有无异常发生。
常使用 finally关闭数据库连接、关闭流等释放资源的操作。防止程序发生异常退出而没有释放相应的资源。
@Test
public void testFinally1() {
System.out.println("结果1:"+a1(null));
System.out.println("-------------");
System.out.println("结果2:"+a1(5));
System.out.println("-------------");
System.out.println("结果3:"+a1(3));
}
public static int a1(Integer aaa) {
try {
if (aaa.equals(5)) {
System.out.println("55555");
return 5;
}
System.out.println("11111");
return 1;
}catch (Exception e) {
System.out.println("22222");
return 2;
}finally {
System.out.println("33333");
return 3;
}
}
22222
33333
结果1:3
-------------
55555
33333
结果2:3
-------------
11111
33333
结果3:3
结论:
从运行结果来看,每次 return 的结果都是3(即finally语句),仿佛其他return语句被屏蔽掉了。
事实也确实如此,因为 finally 用法特殊,所以会撤销之前的 return 语句,继续执行最后的 finally 块中的代码。
@Test
public void test2() {
System.out.println(a2(1));
System.out.println("-------------");
System.out.println(a2(9));
System.out.println("-------------");
System.out.println(a2(6));
}
public static int a2(Integer i) {
System.out.println("start...");
if (i == 1) {return 0;}
System.out.println("before try block");
try {
System.out.println("try block");
if (i == 6) {
System.exit(0);
}
return i;
}finally {
System.out.println("finally block");
}
}
start...
0
-------------
start...
before try block
try block
finally block
9
-------------
start...
before try block
try block
finalize() 是在 java.lang.Object 里定义的,也就是说每一个对象都有这么个方法。
这个方法在 gc 启动,该对象被回收的时候被调用。其实 gc 可以回收大部分的对象(凡是 new 出来的对象,gc 都能搞定,一般情况下我们又不会用 new 以外的方式去创建对象),所以一般是不需要程序员去实现 finalize 的。
一个对象的 finalize() 方法只会被调用一次,而且 finalize() 被调用不意味着 gc 会立即回收该对象,所以有可能调用 finalize() 后,该对象又不需要被回收了,然后到了真正要被回收的时候,因为前面调用过一次,所以不会调用 finalize(),产生问题。
所以,推荐不要使用 finalize() 方法,它跟析构函数不一样。
代码示例:
class C {
public static void main(String[] args) {
new C();
System.gc();
}
protected void finalize() throws Throwable {
System.out.println("finalize execute ... ");
}
}
输出结果:
finalize execute …
PS:如有疑问,欢迎指正。如果觉得不错,点赞支持一下。
------ 更多内容欢迎关注 ----------