Class對象

Class對象:類型信息在運行時是如何表示的溉躲,包含了與類有關(guān)的信息,用于創(chuàng)建類的所有的“常規(guī)”對象的愧薛,Java使用Class對象來執(zhí)行其RTTI酌壕。

類是程序的一部分掏愁,每個類都有一個Class對象,被保存在一個同名的.class文件中,為了生存這個類的對象卵牍,JVM將使用“類加載器"果港。

所有類的都在在對其第一次使用時,動態(tài)加載到JVM中的糊昙。當程序創(chuàng)建第一個對類的靜態(tài)成員的引用時辛掠,就會加載這個類。這個證實構(gòu)造器也是類的靜態(tài)方法,即使在構(gòu)造器之前并沒有使用static關(guān)鍵字萝衩。因此,使用new操作符創(chuàng)建類的新對象也會被當作類的靜態(tài)成員的引用猩谊。

Class的API:###

    getName():全限定的類名

    getSimpleName():不包含包名的類名

    getCanonicalName():全限定的類名

    getInterfaces():返回所有接口的Class對象

    getClassLoader():返回該類的類加載器千劈。

    getComponentType():返回表示數(shù)組組件類型的 Class

    getSuperclass():返回表示此 Class 所表示的實體的超類的 Class。    

    isArray():判定此 Class 對象是否表示一個數(shù)組類牌捷。

Class實例對象的newInstance()方法來創(chuàng)建的類墙牌,必須帶有默認構(gòu)造器。

Class對象的應(yīng)用方法:###

1.Class.forName()

2.類字面常量:類型.class

簡單暗甥,安全喜滨,因為它在編譯時就會受到檢查,不需要try語句包圍淋袖,根除了對forName()方法的調(diào)用鸿市,所以也更高效。

類字面常量不僅可以應(yīng)用于普通的類即碗,也可以應(yīng)用于接口,數(shù)組以及基本數(shù)據(jù)類型陌凳。

當使用“.class”來創(chuàng)建對Class對象的引用時剥懒,不會自動地初始化該Class對象。初始化被延遲到了對靜態(tài)方法(構(gòu)造器隱式地是靜態(tài)的)或者非常數(shù)靜態(tài)域進行首次引用時才執(zhí)行合敦。

泛化的Class引用###

Class<?>與Class等價初橘,但優(yōu)于平凡的Class,非具體的類引用

Class<? extends Number >:任何由Number派生的類

Class<? Super FancyToy>:某個類充岛,它是FancyToy超類

instanceof與Class的等價性###

instanceof和isInstance()生成的結(jié)果完全一樣保檐,且保持類型的概念
Class的equals()和==也一樣,比較實際的Class對象崔梗,沒有考慮繼承

注冊工廠###

靜態(tài)初始化器只有在類首先被加載的情況下才能被調(diào)用夜只。
  使用工廠方法設(shè)計模式,將對象的創(chuàng)建工作交給類自己去完成蒜魄。工廠方法可以被多態(tài)的調(diào)用扔亥,從而創(chuàng)建適當類型的對象。

精簡版(工廠方法就是Factory接口中的create()方法):

public interface Factory<T> { T create();}

泛型參數(shù)T使得create()在每種Factory是實現(xiàn)中返回不同的類型

反射:運行時的類信息(RTTI)

編譯時谈为,編譯器必須知道所有要通過RTTI來處理的類

反射提供了一種機制——用來檢查可用的方法旅挤,并返回方法名。
運行時獲取類的信息的另一個動機:希望提供在跨網(wǎng)絡(luò)的遠程平臺上常見和運行對象的能力伞鲫,即遠程方法調(diào)用(RMI)粘茄。允許一個java程序?qū)ο蠓植嫉蕉嗯_機器上。

Class類與java.lang.reflect類庫一起對反射的概念進行支持秕脓,該類庫包含了Field柒瓣、Method以及Constructor類(每個類都是先了Member接口)儒搭。這些類型的對象是由JVM在運行時創(chuàng)建的,用以表示未知類里對應(yīng)的成員嘹朗。

Constructor->創(chuàng)建新對象
get()和set()->讀取和修改與Field對象關(guān)聯(lián)的字段
invoke()方法->調(diào)用與Method對象關(guān)聯(lián)的方法
getField(),getMethods()和getConstructors()->返回表示字段师妙、方法以及構(gòu)造器的對象數(shù)組

匿名對象的類信息就能在運行時被完全確定下來,而在編譯時不需要知道任何信息屹培。
詳見JDK文檔

對RTTI來說默穴,編譯器在編譯時打開和檢查.class文件;而對于反射機制來說褪秀,.class文件在編譯時無法獲取蓄诽,所以在運行時打開和檢查.class文件。

類方法提取器###

瀏覽實現(xiàn)了類定義的源代碼或者其JDK文檔媒吗,只能找到在這個類定義中被定義和被覆蓋的方法仑氛。反射機制提供了一種方法,使我們能夠編寫自動展示完整接口的簡單工具闸英。

package typeinfo;
import static net.mindview.util.Print.print;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.regex.Pattern;

public class ShowMethod {
    private static Pattern p = Pattern.compile("\\w+\\.");
    public static void main(String[] args) {
        try {
            Class<?> c = Class.forName("typeinfo.ShowMethod");
            Method[] methods = c.getMethods();
            Constructor[] ctors = c.getConstructors();
            for (Method method : methods) {
            print(p.matcher(method.toString()).replaceAll(""));
            }
            for (Constructor constructor : ctors) {
                print(p.matcher(constructor.toString()).replaceAll(""));
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

動態(tài)代理###

代理是基本的設(shè)計模式之一锯岖。它是你為了聽過額外或不同的操作,而插入的用來替代“實際”對象的對象甫何。這些操作通常涉及與“實際”對象的通信出吹,因此代理通常充當中間人的角色。

package typeinfo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface Interface{
    void doSomething();
    void somethingElse(String arg);
}

class RealObject implements Interface{
public void doSomething() {
    System.out.println("doSomething");
}

public void somethingElse(String arg) {
    System.out.println("somethingElse " +arg);
}
}

class DynamicProxyHandler implements InvocationHandler{

private Object proxied;
public DynamicProxyHandler(Object proxied) {
    this.proxied = proxied;
}

public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {
    System.out.println("*** proxy: " + proxy.getClass() + 
            ", method: " + method + ", args: " + args);
    if (args != null) {
        for (Object arg : args) {
                System.out.println(" " + arg);
            }
        }
            return method.invoke(proxied, args);
        }
    }

public class SimpleDynamicProxy {
    
    public static void consumer(Interface iface){
        iface.doSomething();
        iface.somethingElse("bonobo");
    }
    public static void main(String[] args) {
        RealObject real = new RealObject();
        consumer(real);
        Interface proxy = (Interface) Proxy.newProxyInstance(
    Interface.class.getClassLoader(),
                new Class[] {Interface.class},
                new DynamicProxyHandler(real));
        consumer(proxy);
    }
}

通過調(diào)用靜態(tài)方法Proxy.newProxyInstance()可以創(chuàng)建動態(tài)代理辙喂,這個方法需要一個類加載器(通常從已經(jīng)加載的對象中獲取其類加載器)捶牢,一個希望該代理實現(xiàn)的接口列表(不是類或抽象類),以及InvocationHandler接口的一個實現(xiàn)巍耗。

動態(tài)代理可以將所有調(diào)用重定向到調(diào)用處理器秋麸,因此通常會向調(diào)用處理器的構(gòu)造器傳遞給一個“實際”對象的引用,從而使得調(diào)用處理器在執(zhí)行其中介任務(wù)時炬太,可以將請求轉(zhuǎn)發(fā)灸蟆。

在invoke()內(nèi)部,在代理上調(diào)用方法時需要格外小心娄琉,因為對接口的調(diào)用將被重定向為對代理的調(diào)用次乓。
使用Method.invoke()將請求轉(zhuǎn)發(fā)給被代理對象,并傳入必須的參數(shù)孽水。
注釋:內(nèi)容來自《Java 編程思想》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末票腰,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子女气,更是在濱河造成了極大的恐慌杏慰,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異缘滥,居然都是意外死亡轰胁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門朝扼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赃阀,“玉大人,你說我怎么就攤上這事擎颖¢凰梗” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵搂捧,是天一觀的道長驮俗。 經(jīng)常有香客問我,道長允跑,這世上最難降的妖魔是什么王凑? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮聋丝,結(jié)果婚禮上索烹,老公的妹妹穿的比我還像新娘。我一直安慰自己弱睦,他們只是感情好术荤,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著每篷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪端圈。 梳的紋絲不亂的頭發(fā)上焦读,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機與錄音舱权,去河邊找鬼矗晃。 笑死,一個胖子當著我的面吹牛宴倍,可吹牛的內(nèi)容都是我干的张症。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼鸵贬,長吁一口氣:“原來是場噩夢啊……” “哼俗他!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起阔逼,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤兆衅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體羡亩,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡摩疑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了畏铆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雷袋。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖辞居,靈堂內(nèi)的尸體忽然破棺而出楷怒,到底是詐尸還是另有隱情,我是刑警寧澤速侈,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布率寡,位于F島的核電站,受9級特大地震影響倚搬,放射性物質(zhì)發(fā)生泄漏冶共。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一每界、第九天 我趴在偏房一處隱蔽的房頂上張望捅僵。 院中可真熱鬧,春花似錦眨层、人聲如沸庙楚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽馒闷。三九已至,卻和暖如春叁征,著一層夾襖步出監(jiān)牢的瞬間纳账,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工捺疼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留疏虫,地道東北人。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓啤呼,卻偏偏與公主長得像卧秘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子官扣,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容

  • 1 Class對象 理解RTTI在Java中的工作原理翅敌,首先需要知道類型信息在運行時是如何表示的,這是由Class...
    luoxn28閱讀 440評論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理醇锚,服務(wù)發(fā)現(xiàn)哼御,斷路器坯临,智...
    卡卡羅2017閱讀 134,639評論 18 139
  • Class對象是存放在堆區(qū)的,不是方法區(qū)恋昼,這點很多人容易犯錯看靠。類的元數(shù)據(jù)(元數(shù)據(jù)并不是類的Class對象。Clas...
    值得一看的喵閱讀 5,767評論 0 2
  • 感恩父母早上一早過來整理幫光寶起床液肌,感恩阿姨一早打掃房間讓家中整潔挟炬,干凈,感恩黃建教我太極嗦哆,種下健康的種子谤祖,感恩五...
    日精進_a07d閱讀 141評論 0 4
  • 有一場說走就走的旅行。 然而人生的話還是不太夠充實老速。 20歲來臨粥喜,有人說20歲一過30歲40歲都近了快了,一晃一生...
    亦戈夢閱讀 313評論 0 0