說一下final,finally和finalize的區別

1.final 不可變的修飾符,修飾類,方法和變量(成員變量或局部變量)

  • 修飾類

表示該類不可被繼承.final類中所有的成員方法都會隱式的定義爲final方法。

  • 修飾方法
    使用final方法的原因主要有兩個:

(1) 把方法鎖定,以防止繼承類對其進行更改。

(2) 效率,在早期的java版本中,會將final方法轉爲內嵌調用。但若方法過於龐大,可能在性能上不會有多大提升。因此在最近版本中,不需要final方法進行這些優化了。

final方法意味着“最後的、最終的”含義,即此方法不能被重寫。

注意:若父類中final方法的訪問權限爲private,將導致子類中不能直接繼承該方法,因此,此時可以在子類中定義相同方法名的函數,此時不會與重寫final的矛盾,而是在子類中重新地定義了新方法。

  • 修飾變量
     final成員變量表示常量,只能被賦值一次,賦值後其值不再改變。

2.finally 異常處理塊
什麼情況下 try catch finally 的finally不執行?

  • try還沒有執行就拋出異常終止了程序
 int a=1/0;   //這裏拋出除0異常,try塊未進入
    try {
        System.out.println("我是try塊");
    }catch (Exception e){
       // System.exit(0);
        System.out.println("異常塊");
    }
    finally {
        System.out.println("最終塊");
    }
  • 強制退出
try {
        System.out.println("我是try塊");
    }catch (Exception e){
        System.exit(0);   //可以是0,1參數,jvm退出了
        System.out.println("異常塊");
    }
    finally {
        System.out.println("最終塊");
    }

    }

}

易錯點,return,return在try,catch,fianlly裏不會立馬返回數值,他會進行值的傳遞,返回最終的副本值.

    int a = returnNum();
        System.out.println("a:" + a);  

    }

    static int returnNum() {
        int a = 1;
        try {
            return a+= 1;
        } catch (Exception e) {
            return a+= 1;
        } finally {
            return a+= 1;
        }

    }

沒有異常,a的值在try保存副本 1+1=2,接着執行finally a=2+1; 最後返回值3;
發生異常,異常後的try代碼不執行直接跳到catch 最後finally

     int a = returnNum();
        System.out.println("a:" + a);

    }

    static int returnNum() {
        int a = 1;
        try {
            int b=1/0;
            return a+= 1; //前面發生異常,這裏不會執行,直接跳到catch塊
            //int b=1/0;  return後面不能有代碼!!
        } catch (Exception e) {
            System.out.println("異常發生");
            return a+= 1;
        } finally {
            return a+= 1;
        }

    }

3.finalize 虛擬機垃圾回收機制

源碼:

 /**
 垃圾回收時由垃圾回收器對對象調用
*確定不再有對該對象的引用
     * Called by the garbage collector on an object when garbage collection
     * determines that there are no more references to the object.
     * A subclass overrides the {@code finalize} method to dispose of
     * system resources or to perform other cleanup.
     * <p>
     * The general contract of {@code finalize} is that it is invoked
     * if and when the Java&trade; virtual
     * machine has determined that there is no longer any
     * means by which this object can be accessed by any thread that has
     * not yet died, except as a result of an action taken by the
     * finalization of some other object or class which is ready to be
     * finalized. The {@code finalize} method may take any action, including
     * making this object available again to other threads; the usual purpose
     * of {@code finalize}, however, is to perform cleanup actions before
     * the object is irrevocably discarded. For example, the finalize method
     * for an object that represents an input/output connection might perform
     * explicit I/O transactions to break the connection before the object is
     * permanently discarded.
     * <p>
     * The {@code finalize} method of class {@code Object} performs no
     * special action; it simply returns normally. Subclasses of
     * {@code Object} may override this definition.
     * <p>
     * The Java programming language does not guarantee which thread will
     * invoke the {@code finalize} method for any given object. It is
     * guaranteed, however, that the thread that invokes finalize will not
     * be holding any user-visible synchronization locks when finalize is
     * invoked. If an uncaught exception is thrown by the finalize method,
     * the exception is ignored and finalization of that object terminates.
     * <p>
     * After the {@code finalize} method has been invoked for an object, no
     * further action is taken until the Java virtual machine has again
     * determined that there is no longer any means by which this object can
     * be accessed by any thread that has not yet died, including possible
     * actions by other objects or classes which are ready to be finalized,
     * at which point the object may be discarded.
     * <p>
     * The {@code finalize} method is never invoked more than once by a Java
     * virtual machine for any given object.
     * <p>
     * Any exception thrown by the {@code finalize} method causes
     * the finalization of this object to be halted, but is otherwise
     * ignored.
     *
     * @throws Throwable the {@code Exception} raised by this method
     * @see java.lang.ref.WeakReference
     * @see java.lang.ref.PhantomReference
     * @jls 12.6 Finalization of Class Instances
     */
    protected void finalize() throws Throwable { }
}

該方法是Object 對象的方法,文檔中說當該對象沒有任何引用的時候,GC最終調用該方法進行回收資源.
finalize()是Object的protected方法,子類可以覆蓋該方法以實現資源清理工作,GC在回收對象之前調用該方法。

System.gc();

 /**
     * Runs the garbage collector.
     * <p>
     * Calling the <code>gc</code> method suggests that the Java Virtual
     * Machine expend effort toward recycling unused objects in order to
     * make the memory they currently occupy available for quick reuse.
     * When control returns from the method call, the Java Virtual
     * Machine has made a best effort to reclaim space from all discarded
     * objects.
     * <p>
     * The call <code>System.gc()</code> is effectively equivalent to the
     * call:
     * <blockquote><pre>
     * Runtime.getRuntime().gc()
     * </pre></blockquote>
     *
     * @see     java.lang.Runtime#gc()
     */
    public static void gc() {
        Runtime.getRuntime().gc();
    }

執行System.gc()函數的作用只是提醒或告訴虛擬機,希望進行一次垃圾回收。
至於什麼時候進行回收還是取決於虛擬機,而且也不能保證一定進行回收

而finalze是在回收前執行的.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章