只想把基礎打好之-類型信息

運行時類型信息使得你可以在程序運行時發(fā)現(xiàn)和使用類型信息

  1. 為什么需要RTTI(運行時類型信息):比如,我們使用```
    Interface inter=new InterfalceImp();
為了知道這個inter到底是哪個實現(xiàn)類型的實例來方便做對應的操作,例如,三角形是Shape的實現(xiàn)類型,圓也是Shape的實現(xiàn)類型,那我們要針對Shape做旋轉操作,這就要判斷shape倒底是什么類型的對象,因為對圓做旋轉操作毫無意義。
2. Class對象:生成Class對象的引用:Class.forName("全類名")還有使用類字面量:ClassType.class。前一種會拋出異常(ClassNotFoundException),后一種不會。**當使用后一種來創(chuàng)建Class對象的引用時,不會自動地初始化該Class對象**,為了類的使用而做的準備工作有三個:1:加載,2:鏈接,3:初始化。初始化被延遲到了靜態(tài)方法(構造器隱式地是靜態(tài)的)或者非常數(shù)表態(tài)域進行首次引用時才執(zhí)行:
```java
class Initable{
    static final int staticFinal=47;
    static final int staticFinal2=ClassTest.rand.nextInt(1000);
    // static final int staticFinal2=78;
    static {
        System.out.println("Initializing Initable");
    }
}
class Initable2{
    static int staticNotFinal=147;
    static {
        System.out.println("Initializing Initabl2");
    }
}
class Initable3{
    static int staticNotFinal=74;
    static {
        System.out.println("Initializing Initabl3");
    }
}
public class ClassTest {
    public static Random rand=new Random(47);
    public static void main(String[] args){
     Class initable=Initable.class;
     System.out.println("After creating Initable ref");
     System.out.println(Initable.staticFinal);
     System.out.println(Initable.staticFinal2);
     System.out.println(Initable2.staticNotFinal);

        try {
            Class initable3=Class.forName("classtest.Initable3");
            System.out.println("After Initable3 create ref");
            System.out.println(Initable3.staticNotFinal);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}

運行結果:

After creating Initable ref
47
Initializing Initable
258
Initializing Initabl2
147
Initializing Initabl3
After Initable3 create ref
74

如果一個static不是final的,那么在對它訪問時,總是要求在它讀取之前,首先進行鏈接(為這個域分配存儲空間)和初始化(初始該存儲空間)。

  1. cast()轉型:
interface Building{}
class House implements Building{}
public class ClassTest {
    public static void main(String[] args){
         Building building=new House();
         Class<House>  houseType=House.class;
         House house=houseType.cast(building);
         //或者也可以這樣
        house=(House) building;
    }
}

cast方法接受參數(shù)對象,它與上面main方法最后一行相比,做了很多額外的工作 。新的轉型語法對于無法使用普通轉型的情況顯得非常有用,在你編寫泛型代碼時,如果你存儲了Class引用,并希望以后通過這個引用來執(zhí)行轉型,這種情況就會發(fā)生。不過很少有用到,在JAVA SE5中另一個沒有任何用處的新特性就是Class.asSubclass()。該方法允許你將一個對象轉型為一個更具體的對象。

  1. 動態(tài)的instanceof:Class.isInstance方法提供了一種動態(tài)地測試對象途徑。instanceof與isInstance保持了類型的概念,它指的是"你是這個類嗎或是你是這個類的派生類嗎?",而如果用==比較實際的Class對象,就沒有考慮繼承-它是不是影視個確切的類型。
    5.動態(tài)代理:代理是基本的設計模式之一,它是你為了提供額外的或不同操作,而插入的用來代替"實際"對象的對象。Java的動態(tài)代理比代理的思想更近一步,因為它可以動態(tài)地創(chuàng)建代理并動態(tài)地處理對所代理方法的調用。在動態(tài)代理所做的調用都會被重定向到單一的調用處理器上。
interface Interface{
    void doSomething();
    void somethineElse(String string);
}
class DynamicProxyHandler implements InvocationHandler{
    private Object proxied;
    public DynamicProxyHandler(Object proxied){
        this.proxied=proxied;
    }

    @Override
    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);
    }
}
class  RealObject implements Interface{

    @Override
    public void doSomething() {
        System.out.println("realobject doSomething");
    }

    @Override
    public void somethineElse(String string) {
System.out.println("realobject somethingelse:"+string);
    }
}
class SimpleDynamicProxy{
    public static void consumer(Interface iface){
        iface.doSomething();
        iface.somethineElse("kwkw");
    }
}
public class ClassTest {
    public static void main(String[] args){
RealObject real=new RealObject();
SimpleDynamicProxy.consumer(real);
Interface inter= (Interface) Proxy.newProxyInstance(
        Interface.class.getClassLoader(),new Class[]{Interface.class},new DynamicProxyHandler(real)
);
SimpleDynamicProxy.consumer(inter);
    }
}

運行結果:

realobject doSomething
realobject somethingelse:kwkw
*** proxy:class classtest.$Proxy0.method:public abstract void classtest.Interface.doSomething().args:null
realobject doSomething
*** proxy:class classtest.$Proxy0.method:public abstract void classtest.Interface.somethineElse(java.lang.String).args:[Ljava.lang.Object;@4dc63996
 kwkw
realobject somethingelse:kwkw

可以通過靜態(tài)方法Proxy.newProxyInstance可以創(chuàng)建動態(tài)代理。

  1. 空對象:當使用內置的null表示缺少對象時,這顯得枯燥。問題在于null除了在你試圖用它執(zhí)行任何操作來產生NullPointerException之外,它自己沒有任何用處。你可以假設所有對象都是有效的,而不必浪費編程精力支檢查null。
 interface Null{}
 class Person{
     public final String first;
     public final String second;
     public final String address;
     public Person(String first,String second,String address){
         this.first=first;
         this.second=second;
         this.address=address;
     }
     public static class NullPerson extends Person implements Null{
         private NullPerson(){
             super("None","None","None");
         }

     }
     public static final Person NULL=new NullPerson();
 }

你就可以使用Person.NULL來表示Person的空對象。也可以用Person.NULL來判斷空對象了。空對象的邏輯變體是模擬對象與樁。但是模擬對象與樁都只是假扮可以傳遞實際信息的存活對象,而不是像空對象那樣可以成為null更加智能化的替代物。

  1. 接口與類型信息:當我們用B繼承A接口時,并不希望在使用"A a=new B()"初始a之后再將a向下轉型為B的對象實體,這個時候你需要將限定的B的訪問控制符,使得在訪問控制以外的地方不能訪問B,再提供一個public的初始化B的地方。但是我們通過反射任然可以訪問這個B的信息。即使我們發(fā)布編譯之后的文件,任然可以使用JDK自帶的javap反編譯。但是反射也帶來它的好處。在類中留下后門這一事實,也許可以讓你解決某些特定的問題。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,625評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 多態(tài) 任何域的訪問操作都將有編譯器解析,如果某個方法是靜態(tài)的,它的行為就不具有多態(tài)性 java默認對象的銷毀順序與...
    yueyue_projects閱讀 1,088評論 0 1
  • Java經(jīng)典問題算法大全 /*【程序1】 題目:古典問題:有一對兔子,從出生后第3個月起每個月都生一對兔子,小兔子...
    趙宇_阿特奇閱讀 2,069評論 0 2
  • 最近內心有些空虛就在百度里搜一些正能量的美劇,而備受推薦的就是《肖申克的救贖》,既然人都這么火了,豈有不看的道理?...
    小運閱讀 523評論 0 0

友情鏈接更多精彩內容