直接明瞭的告訴你——對象與內存控制

JVM的垃圾回收機制是由一條後臺線程執行的,其自己也是很是消耗內存的,所以,濫用建立對象,會致使性能大大降低,對內存的分配的瞭解就顯得尤其重要java

變量分類

局部變量

  • 形參:存在於方法簽名中定義的局部變量,有方法調用者爲其賦值,隨着方法的結束而消亡git

  • 方法內部變量:在方法內部定義的局部變量,必須在方法內對其進行顯示初始化,隨着方法的結束而消亡github

  • 代碼塊內部的局部變量:在代碼塊內定義的局部變量,必須在代碼塊內對其顯式初始化,隨着代碼塊結束而消亡微信

成員變量

  • 實例變量:非靜態的成員變量,隨着對象的產生,進行初始化等操做,對象結束變量也就消亡ide

  • 類變量:靜態的成員變量,帶有static修飾符,隨着類初始化產生,隨着類消失而消失性能

在建立變量的時候,必定要合法的前向引用。其含義就是先定義的變量不能引用後定義的變量,反之則能夠網站

變量的內存分配

在同一個JVM中每個類只會存在一個Class對象,所以JVM只要分配一塊內存空間給類變量就能夠了,而實例變量則每次建立對象都要爲其分配一塊內存,幾個實例就要建立幾塊內存空間this

實例變量的初始化時機

  1. 定義變量的時候spa

  2. 代碼塊中線程

  3. 構造器中

定義實例變量時指定的初始值、初始化塊中爲實例變量指定初始值的語句的地位是平等的,當通過編譯器處理後,他們都將被提取到構造器中,也就是說在編譯後,初始化都會被放在構造器中按前後順序進行初始化賦值

類變量初始化時機

同一個JVM中,類變量只能初始化一次

  1. 定義變量的時候

  2. 靜態代碼塊

父類構造器

在建立Java對象的時候,都會先去執行該類的父類對象的非靜態代碼塊和構造器,最後纔是該類的非靜態代碼塊和構造器

  • 所謂的隱式調用和顯式調用,其實就是有沒有用super去調用父類的構造器的區別。

  • 若是父類還沒被初始化過,則會最早對類變量進行初始化

訪問子類對象的實例變量

子類的方法能夠訪問父類的實例變量,這是由於子類繼承父類就會得到父類的成員變量和方法,但父類的方法不能訪問子類的實例變量,由於父類沒法知道哪一個子類繼承他

並且子父類中的成員變量(類變量和實例變量)是相互獨立的,父類中的成員變量不會被子類中同名的變量覆蓋

class Base {
    static int count = 2;
}

class Mid extends Base {
    static int count = 20;
    
}

public class Sub extends Mid {
    static int count = 200;

    public static void main(String[] args) {
        // 建立一個Sub對象
        Sub s = new Sub();
        // 將Sub對象向上轉型後賦爲Mid、Base類型的變量
        Mid s2m = s;
        Base s2b = s;
        // 分別經過3個變量來訪問count實例變量
        System.out.println(s.count);
        System.out.println(s2m.count);
        System.out.println(s2b.count);
    }
}

結果

200
20
2

當建立Sub的時候,會初始化Base、Mid和Sub三個對象,同時也就存在三個count變量了,也就是說有三塊內存保存着這三個對象和count變量,以s2m變量爲例,s2m擁有的地址是Sub對象的堆地址,但s2m變量類是是Mid,則會去尋找Mid下的變量值

也就說成員變量的值取決於聲明該變量聲明時是所用的類型

這裏寫圖片描述

訪問子類對象的方法

子類能夠重寫父類的方法,子類也能夠經過super的方式調用父類的方法,在多態的狀況下,子類重寫的方法會覆蓋掉父類的方法

class Base{
    int count =2;
    public void display(){
        System.out.println(this.count);
    }
}
class Derived extends Base{
    int count =20;
    @Override
    public void display() {
        System.out.println(this.count);
    }
}
public class FieldAndMethod {
    public static void main(String[] args) {
        Base b=new Base();
        System.out.println(b.count);
        b.display();
        Derived d=new Derived();
        System.out.println(d.count);
        d.display();
        Base db=new Derived();
        System.out.println(db.count);
        db.display();
        Base b2d=d;
        System.out.println(b2d.count);
    }
}

結果

2
2
20
20
2
20
2

一切在你執行這段代碼以後,你就會明白一切了。

更多內容能夠關注微信公衆號,或者訪問AppZone網站

http://7xp64w.com1.z0.glb.clouddn.com/qrcode_for_gh_3e33976a25c9_258.jpg

相關文章
相關標籤/搜索