final finally finalize的区别

1.final

final修饰符 所标记的成分具有终态的特征,表示最终的意思。

final修饰类,类不能被继承。该类将不具有子类。

final修饰方法,方法不能被重写,在某些特殊情况下jvm会将该类方法直接内联以便于减少函数调用开销,新版本的Jdk并不会以此为优化方式,所以只有当明确该方法不能被子类修改(重写)的时候才使用该关键字

final修饰变量, 如果是基本数据类型,这该数据在初始化后就无法更改其值。如果是引用类型的变量,初始化完成后该变量的引用无法指向其他对象

2. finally

finally 是指用于try{}中必须被执行的部分。

1.常规用法

try{
  xxx
}catch(Exception e){
  xxx
}finally{
  xxx
}

2.finally特殊状态

如果return 在finally中则finally中的代码优先于try块中执行

private String finallyReturnTest(){

      try {
          return "return try";
      } finally {
        return "return finally";
      }
  }

结果:
return finally

从以上运行结果可以看出,当finally块中有return语句时,将会覆盖函数中其他return语句。

final的finally返回对象。

@Test
public void testString() {
    System.out.println(finallyString());
}


private String finallyString() {
    String str = "Hello";
    try {
        return str;
    } finally {
        str = "world";
        System.out.println("finall执行了");
    }
}

结果:
finall执行了
Hello

程序在执行到return时会首先将返回值存储在一个指定的位置,其次去执行finally块,最后再返回。在方法testFinally1中调用return前,先把result的值1存储在一个指定的位置,然后再去执行finally块中的代码,此时修改result的值将不会影响到程序的返回结果。

对于常规类型也是这样的。

private int finallyInt(){
    int x = 10;
    try{
        return x;
    }finally {
        x = 2;
        System.out.println("finally执行了");
    }
}

结果:
finall执行了
10

但是,如果该对象为引用类型,那么方法返回的只是一个对象的引用。所以会改该值。

private StringBuffer finallyStringBuffer(){
     StringBuffer sb = new StringBuffer("Hello");
     try{
         return sb;
     }finally {
         sb.append(" World");
         System.out.println("finally 我被执行了");
     }

 }

结果:

finally 我被执行了
Hello World

如果在finally里return,那么finally赋值操作是有效的。

private String finallyStringReturn() {
    String str = "Hello";
    try {
        return str;
    } finally {
        str = str + "World";
        return str;
    }
}

结果:
Hello World

下面总结下finally执行顺序。

  1. finally 和try中同时发现return ,finally会强制覆盖try中的return。
  2. try中return的如果是final修饰的变量,或者是常规变量,则finally块里的赋值操作无效。先出方法栈然后执行。
  3. 如果try中return的是非finall修饰引用变量,finally里的赋值会改变引用的内容。
  4. 如果在finally里return,那么finally赋值操作是有效的。

finalize

finalize 是一个Object对象的方法,当一个对象被回收时会调用该方法。

常规用法

public class Test {
	@Override
	protected void finalize() throws Throwable {
		System.out.println("我被回收了");
		super.finalize();
	}
}

public class Demo {
	public static void main(String[] args) {
		Test test = new Test();
		test = null;
    //这里的gc调用不是每次都会成功。
		System.gc();
    //简易的增加一个延迟
    try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

结果

我被回收了

posted @ 2018-03-30 13:17  枫飘雪落  阅读(256)  评论(0编辑  收藏  举报