Java - final, finally, finalize 的區別

By sunwc 2023-03-21 Java

finalize 方法

一般來說,在物件被回收之前會先存取 物件.finalize(),但是我們不要主動去調finalize(),gc回收機制會主動去調 物件.finalize()


final 關鍵字

* final 修飾類別: 代表本類別就不能被繼承,例如 String, System, StringBuffer 類別
* final 修飾方法: 代表本方法不能被覆寫 (Override),例如Object類別的getClass()
* final 修飾變數: 代表本變數為常量,不能做修改;可以考慮指定值的位置有:顯示初始化、non-static-block 中初始化、constructor 中初始化

```java
public class SingletonTest2 {

  final int WIDTH;
  final int HEIGHT;
  final double PI;
  
  // non-static-block
  {
    PI = Math.PI;
  }
  // construtor1
  public SingletonTest2() {
    WIDTH = 2;
    HEIGHT = 4;
  }
  
   // construtor2
  public SingletonTest2(int height) {
    WIDTH = 2;
    HEIGHT = height;
  }

}
```

final面試題一、

```java
public class Something {
   public int addOne(final int x) {
    return ++x; // 編譯錯誤
    // return x + 1; // 編譯、執行成功
   }
}
```

final面試題二、

```java
 public class Something {
    public static void main(String[] args) {
      Other o = new Other();
      new Something().addOne(o);
    }
    public void addOne(final Other o) {
      // o = new Other(); // 編譯錯誤
      
      // 被加上final的物件 其屬性是可以修改的
      o.i++; // 編譯、執行成功 
    }
 }
 class Other {
    public int i;
 }
```

* stactic final修飾屬性:代表本屬性為 全局常數


---

try-catch-finally:

  • finally 區塊:一定會被執行的程式

    • 當 catch 區塊中又出現例外
    • 當 try 區塊有 return 語句
    
    public class ExeptionTest {
    
    
      public static void main(String[] args) {
    
        ExeptionTest exeptionTest = new ExeptionTest();
        String numberString = exeptionTest.exceptionTest();
    
        System.out.println(numberString);
      }
    
    
      public String exceptionTest() {
    
        try {
          int[] arr = new int[3];
          System.out.println(arr[3]);
    
          return "0";
        } catch (ArrayIndexOutOfBoundsException e) {
          System.out.println("進catch~");
          return "1";
        } finally {
          System.out.println("進finally~");
          return "2";
        }
      }
    }
    

    輸出結果:(finally 區塊執行完畢後,才會執行其他區塊的 return 語句)

    進catch~
    進finally~
    2
    

finally 關閉資源

  • JVM 對於物理連接,例如資料庫連線、輸入輸出流、Socket連線銷毀無能為力,否則有內存洩漏的危險,此時資源的釋放,就需要宣告在finally中

    @Test
    public void testFinallyClose() {

       FileInputStream fis = null;
      try {
        File file = new File("hello.txt");
        fis = new FileInputStream(file);

        // 讀取一個字符
        int data = fis.read();
        while(data != -1) {
          System.out.print((char) data);
          data = fis.read();
        }
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      }  catch (IOException e) {
        e.printStackTrace();
      } finally {
        if (fis != null) {
      	  try {
      		  fis.close();
        } catch (IOException e2) {
          e2.printStackTrace();
        }
        }
      }
    }

總結

面試中考題層出現問它們三倆有什麼關係 final, finally, finalize,其實並沒有關係,只是長得像就被放在一起了,透過這篇文章能夠更了解各自的意義,不要下次又搞混了就好了 :)