摘要:找到字節(jié)碼并創(chuàng)建一個對象。鏈接,檢驗(yàn)字節(jié)碼,為字段分配存儲空間,解決其對他類的引用。初始化,如果有父類則初始化父類,執(zhí)行靜態(tài)初始化器和靜態(tài)初始化區(qū)塊直到第一次訪問靜態(tài)成員時初始化才執(zhí)行。如果成員不是編譯時常量由初始化器賦值,也會引起初始化。
有兩種形式在運(yùn)行時獲取類型信息:
傳統(tǒng)的RTTI
反射
Class對象運(yùn)行時的類型信息是通過Class對象表現(xiàn)的,它包含了類的信息。所有“普通的”對象都是通過Class對象創(chuàng)建的。Java通過Class對象實(shí)現(xiàn)RTTI。
在你的程序中每個類都對應(yīng)一個Class對象。每次編寫并編譯一個新的類時都會創(chuàng)建一個相應(yīng)的Class對象,并且以.class文件儲存起來。JVM用class loader子系統(tǒng)創(chuàng)建對象。
JVM有一個原生的class loader用來加載“可信類”,包括JAVA API中的類。你也可以實(shí)現(xiàn)自己的帶有特殊目的的class loader并與原生的串聯(lián)起來。
在一個類第一次被訪問static成員時,這個類則被加載到JVM。構(gòu)造函數(shù)也是靜態(tài)的,所以用new創(chuàng)建對象時也算訪問了static成員。因此Java程序運(yùn)行前并不是完全加載了。
class loader先檢查類型的Class對象是否加載了,如果沒加載,class loader會找到.class文件(其他的class loader可能會從別處加載二進(jìn)制碼,比如從數(shù)據(jù)庫)。字節(jié)被加載之后會被驗(yàn)證一下有沒有損壞或者有沒有不安全的代碼。
Class對象被加載到內(nèi)存之后,將被用來創(chuàng)建這個類型的所有對象。
所有Class對象都屬于Class類,和其他類一樣可以使用引用操作Class對象。一種獲得Class對象的方法是調(diào)用靜態(tài)的forName()方法,這個方法接收一個字符串類型,是類的名字,需要使用包括報名的全名。如果找不到.class文件,會拋出一個ClassNotFoundException。
在運(yùn)行時,使用類型信息之前要先獲取Class對象。Class.forName()是比較方便的做法。如果已經(jīng)有一個這個類型的對象了,可以調(diào)用對象getClass()方法,這個方法是在Object里定義的。
Class literals除了forName()外,Java還提供一種獲得Class對象引用的方法,比如Toy.class。這種方法更簡潔和更安全,因?yàn)檫@種方法的類型在編譯時就會被檢查。
基本類型的包裝類有一個標(biāo)準(zhǔn)字段TYPE,提供了基本類型的Class對象,例如:boolean.class <=> Boolean.TYPE。
__使用.class獲得Class對象引用不會初始化Class對象__。獲得一個可用的類需要三步
加載,由類加載器完成。找到字節(jié)碼并創(chuàng)建一個Class對象。
鏈接,檢驗(yàn)字節(jié)碼,為static字段分配存儲空間,解決其對他類的引用。
初始化,如果有父類則初始化父類,執(zhí)行靜態(tài)初始化器和靜態(tài)初始化區(qū)塊
直到第一次訪問靜態(tài)成員時初始化才執(zhí)行。
用Class.forName()獲得引用則會引起初始化。
如果static final成員是編譯時常量,訪問這個成員則不會引起初始化。如果static final成員不是編譯時常量(由初始化器賦值),也會引起初始化。訪問不是final的static成員總會引起鏈接和初始化,即分配存儲和初始化值。
Generic class referencesClass> <=> Class
使用generic語法可以讓你在編譯時就發(fā)現(xiàn)類型不對的錯誤。只用Class的話,如果犯了錯誤到運(yùn)行時才會發(fā)現(xiàn)。
New cast syntax//: typeinfo/ClassCasts.java class Building {} class House extends Building {} public class ClassCasts { public static void main(String[] args) { Building b = new House(); ClassChecking before a casthouseType = House.class; House h = houseType.cast(b); h = (House)b; // ... or just do this. } } ///:~
RTTI的三種形態(tài):
傳統(tǒng)的類型轉(zhuǎn)換,使用RTTI來確保類型轉(zhuǎn)換時正確,如果不正確會拋出ClassCastException異常
以Class object表示對象的類型。Class對象可以提供很有用的運(yùn)行時信息。
instanceof,檢驗(yàn)對象是不是某類型。(動態(tài)Class.islnstance())
反射RTTI可以提供類型信息,但是如果在編譯時并不知道對象所屬類的信息(比如從硬盤或網(wǎng)絡(luò)讀取的字節(jié)所組成的類),則無法使用RTTI。
Class類和java.lang.reflect中的Field, Method, and Constructor(實(shí)現(xiàn)了Member接口)一起支持了反射的概念。在運(yùn)行時,JVM會創(chuàng)建這些類型的對象來表示未知類的成員。
使用反射前提是JVM可以找到未知類型的.class文件(從硬盤中的文件或者網(wǎng)絡(luò))。
RTTI在編譯時,由編譯器打開和檢查.class文件。
在反射機(jī)制中,.class在編譯時是不可用的,.class是由運(yùn)行環(huán)境在運(yùn)行時打開和檢查的。
接口和類型信息利用反射可以訪問對象的方法和成員變量,不論訪問修飾符是什么。但是反射不能修改final的變量,在運(yùn)行時試圖修改final字段不會報錯,但是實(shí)際上修改并沒有生效。
概念class | type | .class文件 | Class | Class object | Class reference |
---|---|---|---|---|---|
java中的類 | 類型,對應(yīng)于一個類,每個類都是一個類型 | 用來儲存Class對象,程序中編寫的每個類,都會被編譯成一個.class文件 | 一種叫“Class”的類 | Class類的一個實(shí)例,這個類由.class文件而來,負(fù)責(zé)創(chuàng)建它所表示的類的實(shí)例 | Class object的引用,包括了這個類的statics |
一個類默認(rèn)的構(gòu)造器和這個類有相同的訪問修飾符
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/70932.html
摘要:通過運(yùn)行時類型信息,程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對象的實(shí)際派生類型。編程應(yīng)該盡量面向接口編程,應(yīng)該對類型信息盡量的少了解二對象看書,書上寫得好靜態(tài)語句塊在這個類被加載的時候運(yùn)行。 一、為什么需要RTTI Run-Time Type Information。通過運(yùn)行時類型信息,程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對象的實(shí)際派生類型。編程應(yīng)該盡量...
摘要:公司的和作為主要人員創(chuàng)作了其中在年月發(fā)布在年月發(fā)布。的核心理念是對象都是運(yùn)動和變化的比如天氣。也是對象都是相互關(guān)聯(lián)的比如天氣和人的行為。對象的變化都是在同時并行的比如馬路上,機(jī)動車道上的汽車和非機(jī)動車道路上的人都是同時運(yùn)行的。 前言公司用到rxjava,學(xué)習(xí)Learning-Rxjava筆記本書源碼位置:https://github.com/PacktPubli... 1.A brie...
摘要:擴(kuò)展單一職責(zé)原則又稱單一功能原則,面向?qū)ο笪鍌€基本原則之一。馬丁表示此原則是基于湯姆狄馬克和的著作中的內(nèi)聚性原則發(fā)展出的。 [解讀]Thinking in React 原文:http://facebook.github.io/react/docs/thinking-in-react.html 前言 Thought is the seed of action 這是放置在官方的QUICK ...
摘要:內(nèi)部類中也可以取得這個外部類對象引用。創(chuàng)建成員內(nèi)部類對象的時候需要外部類對象。另外在方法中的內(nèi)部類不能加等權(quán)限修飾符,只能加和修飾符。可以在接口內(nèi)部定義內(nèi)部類,而且他們即使沒有修飾,也會自動變成的。 Thinking in Java撈干貨,寫筆記 一、成員內(nèi)部類 1.最基本使用 public class Demo { class Contents{ privat...
摘要:而這可以通過注解辦到,在代碼中以指令語言的形式化方法來為代碼提供更多信息。有注解的說明這個成員變量是一個列名,然后根據(jù)注解信息來生成相應(yīng)的語句。也就是說把注解信息提取了出來。 注解是向代碼中添加信息的一種方法,并且在之后還可以使用這些數(shù)據(jù)就比如這個方法是用來剝香蕉的,但是我們看就是一串代碼,我們沒辦法在代碼里寫一段指令說我這個程序是用來剝香蕉的,當(dāng)然除了注釋。而這可以通過注解辦到,在代...
閱讀 1972·2021-09-09 09:33
閱讀 1113·2019-08-30 15:43
閱讀 2662·2019-08-30 13:45
閱讀 3304·2019-08-29 11:00
閱讀 854·2019-08-26 14:01
閱讀 3568·2019-08-26 13:24
閱讀 477·2019-08-26 11:56
閱讀 2686·2019-08-26 10:27