亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

左右對象在運行時或編譯時評估/解析?

左右對象在運行時或編譯時評估/解析?

守候你守候我 2022-12-28 10:48:11
參考書本練習...有以下代碼..Left left = createLeftInstance (); Right right = createRightInstance ();...并考慮到上述兩種方法都可以返回 Left 和 Right 的所有子類的實例,在 Java 中調用以下方法...left.invoke (right);怎么解決的:A)基于左側的運行時類型和右側的編譯時B) 基于左邊的編譯時類型和右邊的運行時類型C) 基于左邊的編譯時類型和右邊的編譯時類型D)基于左邊的運行時類型和右邊的運行時
查看完整描述

3 回答

?
紅糖糍粑

TA貢獻1815條經驗 獲得超6個贊

實際上,我認為技術上正確的答案是“以上都不是”。

  • 在編譯時,你需要知道left變量(Left)和right變量(Right)的聲明類型。這將決定該方法的哪個方法重載1Left::invoke最適用于 type 的參數Right

  • 在運行時, 的實際類型left將決定調用哪個實際方法。

所以完整的答案是:

E) 基于 的編譯時和運行時類型left以及 的編譯時類型right。

但是,我懷疑教科書上這個問題的重點是幫助你區分非重載方法的編譯時解析和運行時方法調度。為此,A) 是“足夠正確”的。


1 - 為了做出決定,編譯器需要將其超類型與聲明Right的方法及其超類型的不同方法重載進行比較。如果有多個重載,編譯器需要選擇“最具體適用”的重載。invokeLeft


查看完整回答
反對 回復 2022-12-28
?
慕無忌1623718

TA貢獻1744條經驗 獲得超4個贊

A) 是這里的正確答案。


下面的代碼演示了這一點。


    public class Main001 {


        public static void main(String[] args) {

            A right = createRightInstance();

            B left = createLeftInstance();


            left.invoke(right);

            System.out.println("Done!!!");

        }


        public static B createLeftInstance() {

            return new B2();

        }


        public static A createRightInstance() {

            return new A2();

        }


    }


    class A{


    }


    class A1 extends A{


    }


    class A2 extends A1{


    }


    class B{

        public void invoke(A x) {

            System.out.println("Invoking method A on B with argument " + x.getClass().getName());

        }

        public void invoke(A1 x) {

            System.out.println("Invoking method A1 on B with argument " + x.getClass().getName());

        }

        public void invoke(A2 x) {

            System.out.println("Invoking method A2 on B with argument " + x.getClass().getName());

        }

    }


    class B1 extends B{

        public void invoke(A x) {

            System.out.println("Invoking method A on B1 with argument " + x.getClass().getName());

        }

        public void invoke(A1 x) {

            System.out.println("Invoking method A1 on B1 with argument " + x.getClass().getName());

        }

        public void invoke(A2 x) {

            System.out.println("Invoking method A2 on B1 with argument " + x.getClass().getName());

        }


    }


    class B2 extends B1{

        public void invoke(A x) {

            System.out.println("Invoking method A on B2 with argument " + x.getClass().getName());

        }

        public void invoke(A1 x) {

            System.out.println("Invoking method A1 on B2 with argument " + x.getClass().getName());

        }

        public void invoke(A2 x) {

            System.out.println("Invoking method A2 on B2 with argument " + x.getClass().getName());

        }

    }

這個例子打印


Invoking method A on B2 with argument A2

Done!!!

這意味著 A) 是正確答案。


為什么是這個意思?


嗯......因為:

1)調用了 B2 類的方法(如輸出所示)并且 B2 是運行時類型left(編譯時類型left是 B)。

2) 調用了一個帶參數 A 的方法(注意 A 是 的編譯時類型right),即使 的運行時類型right是 A2。編譯時類型 ofright只是right聲明的類型,即 A。運行時類型 ofright是參數的實際類型,即 A2(請參閱輸出,它with argument A2在那里說明)。


查看完整回答
反對 回復 2022-12-28
?
翻翻過去那場雪

TA貢獻2065條經驗 獲得超14個贊

Java 有A,它被稱為single dispatch

  • 方法重載由編譯器在編譯時選擇(將 的編譯時類型與 的編譯時類型right提供的方法相匹配left

  • 方法調用發生在運行時類型上left——因為方法不會消失,left當然有一個方法具有在編譯時選擇的相同簽名。此行為算作“調度”,并且因為它僅取決于left(在運行時),所以它是“單一的”。

使用內置println(Object)and的超級簡單演示println(char[])

char c[]={'a','b','c'};

System.out.println(c);

Object o=c;

System.out.println(o);

它會產生類似的結果


abc

[C@1540e19d

第一行顯示連接字符數組,第二行顯示在編譯時傳遞println(char[])的完全相同的數組(可以添加一些檢查,如)導致調用重載,而不管運行時類型如何。println(o==c);Objectprintln(Object)


B和C可能不存在。


D稱為多重分派,當方法簽名也在運行時使用參數的實際運行時類型選擇時,并且所選方法在 的運行時類型上被調用left。java默認是不支持的,可以用反射來實現,下面是一個單參數的例子:


public static void trickyprintln(Object o) throws Exception {

    System.out.getClass().getMethod("println",o.getClass()).invoke(System.out,o);

}


public static void main (String[] args) throws Exception {

    char c[]={'a','b','c'};

    trickyprintln(c);

    Object o=c;

    trickyprintln(o);

}

這一個導致


abc

abc

asprintln是手動選擇的,使用參數的運行時類型。所以如果有人真的需要它,在 Java 中是可以做到的,但它不會自動發生。


查看完整回答
反對 回復 2022-12-28
  • 3 回答
  • 0 關注
  • 108 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號