كيف طريقة جافا العمل على إيفاد مع الوراثة وفئات مجردة؟

StackOverflow https://stackoverflow.com/questions/452635

  •  19-08-2019
  •  | 
  •  

سؤال

وركضت إلى الوضع اليوم حيث جافا لم يكن استدعاء الأسلوب كنت أتوقع - هنا هو حالة اختبار الحد الأدنى: (أنا آسف هذا يبدو المفتعلة - سيناريو "العالم الحقيقي" هو إلى حد كبير أكثر تعقيدا، ويجعل أكثر بكثير من الشعور "لماذا بحق الجحيم يمكن أن تفعله أن ؟" وجهة نظر.)

وأنا مهتم بشكل خاص في لماذا يحدث هذا، وأنا لا يهمني اقتراحات إعادة تصميم. لدي هذا الشعور هو في جافا الألغاز، ولكن ليس لدي نسختي مفيد.

واطلع على سؤال محدد في داخل تثني اختبار .getValue () أدناه:

public class Ol2 {  

    public static void main(String[] args) {  
        Test<Integer> t = new Test<Integer>() {  
            protected Integer value() { return 5; }  
        };  

        System.out.println(t.getValue());  
    }  
}  


abstract class Test<T> {  
    protected abstract T value();  

    public String getValue() {  
        // Why does this always invoke makeString(Object)?  
        // The type of value() is available at compile-time.
        return Util.makeString(value());  
    }  
}  

class Util {  
    public static String makeString(Integer i){  
        return "int: "+i;  
    }  
    public static String makeString(Object o){  
        return "obj: "+o;  
    }  
} 

والإخراج من هذا الرمز:

obj: 5
هل كانت مفيدة؟

المحلول

لا، نوع قيمة غير متوفر في وقت الترجمة. نضع في اعتبارنا أن javac وتجميع نسخة واحدة فقط من رمز لاستخدامها في جميع المحتملة T. وبالنظر إلى أن النوع الوحيد الممكن للمترجم لاستخدامها في getValue الخاص بك () الأسلوب هو كائن.

وC ++ هو مختلف، لأنه سيخلق في نهاية المطاف إصدارات متعددة جمعت من قانون حسب الحاجة.

نصائح أخرى

ولأن اتخاذ القرار حول ما makeString() لاستخدامها في الترجمة من الوقت، واستنادا إلى حقيقة أن T يمكن أن يكون أي شيء، يجب أن تكون النسخة Object. فكر في الأمر. إذا كنت فعلت Test<String> فإنه سيتعين عليها أن استدعاء إصدار Object. على هذا النحو كافة مثيلات Test<T> سوف تستخدم makeString(Object).

والآن إذا كنت فعلت شيئا مثل:

public abstract class Test<T extends Integer> {
  ...
}

والامور قد تكون مختلفة.

وجوش بلوخ <م> الفعال جافا لديه نقاشا ممتازا توضيح الالتباس الذي يطرح نفسه لارسال يعمل بشكل مختلف عن طاقتها مباراة يتم تجاوز (في فئة فرعية) الأساليب. الاختيار بين زائد طرق --- موضوع هذا السؤال --- يتحدد في وقت الترجمة. الاختيار بين تجاوز يتم الأساليب في وقت التشغيل (وبالتالي يحصل على معرفة نوع معين من وجوه).

وهذا الكتاب هو أكثر وضوحا بكثير من تعليقي: انظر "البند 41: استخدام الحمولة الزائدة بحكمة"

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top