国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Java中關于先有雞還是先有蛋的問題----Class&Object

2019-11-14 14:53:40
字體:
來源:轉載
供稿:網友

 在java中,我們常常會看到一個類型:Class。并且在類似Person.class,cache.getClass()等代碼中見到它的身影。

眾所周知,Class是用來描述一個類的類型,而Object是所有對象的最終父對象。那么就會引申出下邊的兩個結論:

1、如果從對象的角度來看,那么肯定是先有Object對象,其次才有其派生的對象Class。

2、Class表示的是類、對象,肯定是先有類這個概念,其次才有各個類型(抽象的、非抽象的),包括Object。

這就會出現一個問題,到底是先有Class(雞)還是先有Object(蛋)?

 

好吧,此處先給出答案,是先有Object,然后才有Class的。

原因是Object,是所有對象的最終父對象,而Class本身也是一個對象。所以是先有Object,然后才Class對象的。

那么如何解釋第二點呢? 這是因為一個概念被混淆了。

在Java中,所有的對象都派生自Object,而Class類(注意此處是大寫也是一個類)所以他也繼承自Object,這個我們可以在eclipse里邊通過查看類的繼承關系清楚的看到。

在Java中,還有一個class(注意此處是小寫)。他表示的是一個個(防盜連接:本文首發自http://m.survivalescaperooms.com/jilodream/ )對象,也就是一個個類。Object是這些對象的其中之一。同時在這些對象中有一個對象,它的作用是用來識別標記其它對象的內容,這個類叫做Class(注意此處是大寫)。 因此就會出現有一個class的名字叫做Class。而問題中將class等價于Class,很顯然是不合理的。兩者完全不在一個維度里。

但是問題還是會出現,在加載Object時(尚未完成加載時),究竟如何實現為其加載對應的Class的呢?這個就涉及到對象最初是如何被系統加載的。這里JVM啟動時使用的是C++代碼對這些最初的核心類進行表示。分配好內存空間后,互相建立引用,進而才完成類的初始化。所以可以看到如果從JVM實現的角度來說,二者是同時完成加載的。ps 而且面相對象的語言遇到類似的問題,通常也都是通過自舉的形式解決最初系統加載順序的問題(此處藍色字體感謝@之奇一昂的糾正,原文有偏差已修改)

 

拋磚引玉----深入學習Class類

解了class,Object,Class的關系,我們接下來深入說說Class類。(這才是這篇博客的主要目的)

 一、背景知識

類對象在使用之前都會被JVM加載(其實是經過加載、連接、初始化三個步驟對類完成初始化)。類加載指的就是JVM將class文件讀入內存,并為之創建一個Class對象。同時當一個類被加載后,再次使用時,就不會被重復加(防盜連接:本文首發自http://m.survivalescaperooms.com/jilodream/ )載。這樣新建的Class與加載的class就形成一一對應的關系。 通過該Class對象,就可以訪問到對應的class。所以我們可以把Class理解為一個類的標識對象,它相當于是一個類的標簽(銘牌)。拿到一個Class,我們就可以找到對應的類(class)。

二、獲取Class對象的方法

在Java中我們可以使用三個方法拿到Class對象。其中兩種是針對已經在家的類對象,去獲得他對應的Class對象。剩余一種利用到了反射,根據提供的類名去尋找對應的class文件,進而找到Class對象。

 

1 Class.forName(String className)//className表示完整的名稱,包括該類的包名。如果無法找到,該方法會拋出一個 2 Person.class //Person代表的是一個類,class字段是其默認的屬性 3 person.getClass() //getClass是Obj類的一個實例方法,所有的類都有該方法,包括Class類 

 

三、 從Class中可以獲取到的信息

系統可以通過Class對象,找到該對象對應的class.而Class對象包含了class的基本詳細信息。這些信息可以分為以下四個方面: 1、獲取到class所包含的構造器。 2、獲取到class所包含的方法。 3、獲取到class所包含的成員變量。 4、獲取到class所包含的Annotation。 ps 很多小伙伴可能對Annotation不太熟悉,這里簡單說下:Annotation翻譯為注解,本身也是一個類,可以用來保存類的描述信息。 有興趣的可以參考下面這篇文章:

http://m.survivalescaperooms.com/peida/archive/2013/04/24/3036689.html

四、在工作中Class類的使用用途

在這里我總結了一下曾經遇到的使用情況,將其分為;兩方面,如果有遺漏,大家可以補充。

1、對對象類型的使用和校驗

有些時候,我們需要對傳入對象的類型進行校驗,判斷傳入的對象是否為我們需要的類型。 

if(para.getClass==Person.class)//如果這里使用 instance關鍵字,則可能會受到Person類繼承關系的干擾,導致無法進行正確的判斷。 

 

2、反射

<1>用字符串定義需要加載的類名,然后等到需要時候再加載。

  這樣做有三個用途:

  (1)有時候并不知道此處需要加載的類型,需要在運行時才可能知道需要加載哪個class,譬如在運行的過程中,根據用戶的手動設置,動態的選擇接下來要加載的類。  

  (2)在編譯時已經知道需要加載的類名,但是尚無需要加載的.class文件,需要在運行時,通過用戶上傳,或者后臺到指定地址下載class文件。   插件化開發的實現就是使用這樣一個原理。舉兩個例子:

      (α)用戶在使用過濾時,需要自己來定義一套復雜的過濾機制,這時可能就無法通過界面簡單的設置一下需要過濾的內容。可以由用戶手動的上傳自己的過濾算法的jar包,然后由后臺動態的加載,使用該算法。

      (β)亦或者有時候在工作環境中,對于皮膚顯示有一套默認的顯示效果,同時也支持用戶自己上傳需要顯示效果的jar包。后臺拿到用戶上傳的jar包后,反射出需要用到的特效算法,形成動態的交互。  

  (3)縮短編譯時間,加快啟動軟件的速度(包括client 和server)  

  在啟動時,包含main方法的類被加載,同時它會加載(防盜連接:本文首發自http://m.survivalescaperooms.com/jilodream/ )所自己需要的類。這些類再一次加載自己所需要的類。形成遞推關系。但是對一個大應用程序來說,整個的啟動(加載)過程耗費的時間,常常讓用戶無法忍受,甚至在還未加載完時就被強制關閉了。

  針對這種情況,我們就可以在mian方法類中加載一些最基本的類。諸如登錄、驗證等。當登錄驗證沒有問題之后,需要進入業務操作時,才會根據用戶的選擇,   加載用戶需要的類。從而提高軟件整體的運行效率和用戶體驗。

<2>對于工具的開發和使用

當我們開發工具或腳本時,除了使用系統公開的API外,有時還需要用到原有代碼中被私有化的一些變量和方法。這時僅僅使用繼承是不夠的,還需要反射出對象,拿到其中的變量或調用其中的方法。 比如平常使用的UT框架,有時為了測試效率,就提供了很多可以直接調用待測試類私有方法的API。

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 丹东市| 彝良县| 睢宁县| 益阳市| 朝阳区| 屯留县| 苏州市| 安阳市| 卢湾区| 孟州市| 淅川县| 宁晋县| 屏山县| 阿拉善左旗| 龙泉市| 南城县| 西安市| 张北县| 新丰县| 淳化县| 娱乐| 和田市| 滦平县| 斗六市| 贵德县| 台南市| 彰化县| 上思县| 含山县| 扶余县| 金阳县| 阜宁县| 攀枝花市| 伊春市| 龙泉市| 茶陵县| 都安| 博湖县| 红桥区| 晋江市| 绥江县|