類與對象深度解析

類是對象的藍圖,對象是類的產物

類:是java代碼中的類型,每個對象都有自己的類型。

假設java虛擬機通過Person類文件所在的路徑【當然加載的方式有很多種,可以通過磁盤文件,網絡字節流,動態代理生成class字節流、zip等壓縮文件讀取、JSP轉化、數據庫讀取字節流等,JVM都是直接與字節流進行交互的】加載完成Person.java後,會將該類文件生成的數據保存在方法區,並返回得到一個Class<Person>對象,該Class對象將會作爲Person類的對外接口,由此可以得到類的所有數據。

當Person person = new Person();執行時,將會對Person進行實例化,即執行上述的動作,得到Class<Person>對象,最常用的是通過Class.getDeclaredConstructor().newInstane()來初始化Person類,從而得到person實例。因此Person是製造一切person實例的模板,也可稱爲工廠。

對象

對象=數據(實例狀態)+操作(實例方法、行爲)

其實,程序也等於數據+操作。

區別一點,static變量和static方法雖然實例對象可以使用,但其實它是實例共享的,而非實例私有的,因此可以直接通過類名調用。

實例私有與實例共享:如果是實例私有,那麼實例內部改變這個變量,不會影響其它實例的對應變量;如果是實例共享,那麼任何一個實例改變了該變量,都會使其它實例得到變化後的該變量,而這正是併發問題的來源之一,之所以會有併發問題,就是因爲多個線程同時修改共享變量,導致了數據的不一致性。

另外,static變量和實例變量保存在JVM中的區域也不一樣。

static方法只能訪問static變量,不能訪問實例變量,原因很明顯,因爲static方法可以在類未初始化的時候調用,如果方法中存在實例變量,而實例又不存在,那肯定是矛盾的。

static變量的調用會導致類的加載(而不是初始化,加載是指JVM加載字節碼到內存中,並生成對應的Class對象,初始化是生成對應的類實例,是在類加載之後。)

static內部類的一大好處是,可以在不用初始化外部類的情況下,直接通過外部類類名訪問內部類,就如同通過外部類類名訪問static變量和方法一樣。

對象存儲位置

對象實例化後會存儲在堆內存中,也稱爲方法區,其實保存的數據主要是域數據(包括static、final常量等)、其它的常量池數據(JVM加載後得到class文件結構中,會保存一系列類文件的數據到常量池中,格式爲CONSTANT_xxx_info表結構,包括包名、類名、方法名、方法參數、方法返回值、域名、域類型、域值等)等。

當JVM內存不夠的時候,將會進行內存回收,此時就會將不使用的class文件結構和域數據清理掉,從而騰出空間爲其它實例進入做準備。

變量

變量:

類型上來分,爲primitive主數據類型(boolean byte char short int float long double)和引用(String Array Person...)

位置上來分,爲實例變量(此處將static也作爲實例變量)、局部方法變量

沒有對象變量,沒有那麼大的容器可以裝得下整個對象;但是有指向對象的引用變量,引用變量保存的是對象的方法,而對象是保存在堆上的。

沒有對象變量,沒有那麼大的容器可以裝得下整個對象;但是有指向對象的引用變量,引用變量保存的是對象的方法,而對象是保存在堆上的。

變量引用存儲的是取得特定對象的位表示法

同一個java虛擬機下引用變量的大小是一樣的。

對象引用的值爲null,它也同樣佔用空間。

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