Java介面為什麼不能例項化

kboypkb發表於2021-09-09
Thread t = new Thread(new Runnable(){
    @Override
    public void run(){
       ...
    }
})

介面不能例項化,Runnable是一個介面,此處不是用new來例項化了嗎?這個其實就是一個假象的例項化而已,這種叫做匿名內部類,實質的程式碼等同於如下程式碼:

class MyThread implements Runnable{
    @Override
    public viod run(){
        ...
    }
}
//另一個類的main方法中
Thread t = new Thread(new MyThread());

只是上面的程式碼省略掉了類的名字而已。

Java介面為什麼不能例項化呢?例項化實際意義是在jvm的堆中開闢出一塊記憶體空間,比如Person per = new Person();此處宣告 Person 物件 per,並且例項化一個 Person 物件,實則是在堆中開闢出一塊空間來存放 Person 物件,per則是指向這塊空間,也就是記憶體中的一塊地址。這塊地址中所存放的值就是我們這個 Person 物件的一些屬性。

具體類所佔用的記憶體空間(也就是堆記憶體)所存放的值是類的成員變數,見下圖:
圖片描述
圖中可以看到,棧中存放的是per,值是堆中具體 Person 這個物件的地址,也就是 per 指向這個具體類的引用。而堆中一塊地址,存放的值是 Person 這個類的成員變數(區域性變數在執行時存放在棧中)。

那麼換做一個介面呢?假設我們可以 new 出一個介面,那麼這個介面就會佔用堆中的一塊地址,那麼我們想想介面的這塊地址上能夠存放什麼值呢。

說到這個首先要清楚介面中允許有什麼:靜態的屬性以及方法宣告。這裡再說明下,Java的記憶體空間分為四類:棧(stack)、堆(heap)、程式碼(code)、靜態資料(data)。由此可見介面中所有的東西的具體值都是存放在程式碼區和靜態資料區的,所以介面的這塊地址上並沒有任何實際的值需要儲存,那就沒有必要給它一塊地址來浪費空間。其實用底層程式碼在記憶體中開闢出一塊空間很容易,Java之所以設定不允許介面例項化,那就是介面的例項化沒有任何實際意義,只會佔用一塊記憶體空間,卻不會在這塊空間中放任何實際的值。所以Java主動去規避掉了這個問題。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1916/viewspace-2821765/,如需轉載,請註明出處,否則將追究法律責任。

相關文章