هل يمكن تجنب التحذيرات غير المحددة عند تجاوز طريقة بمعلمات النوع الخام؟

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

سؤال

أقوم بتوسيع فصل دراسي محدد في مكتبة لا أستطيع تغييره:

public class Parent
{
    public void init(Map properties) { ... }
}

إذا كنت أقوم بتعريف فئة "طفل" تمتد إلى الأصل وكنت أستخدم Java 6 مع الأدوية العامة، فما هي أفضل طريقة لتجاوز طريقة init دون الحصول على تحذيرات لم يتم التحقق منها؟

public class Child extends Parent
{
    // warning: Map is a raw type. References to generic type Map<K,V> should be parameterized
    public void init(Map properties) { }
}

إذا قمت بإضافة معلمات عامة، أحصل على:

   // error: The method init(Map<Object,Object>) of type Child has the same erasure as init(Map) of type Parent but does not override it
   public void init(Map<Object,Object>) { ... }
   // same error
   public void init(Map<? extends Object,? extends Object>) { ... }
   // same error
   public void init(Map<?,?>) { ... }

يحدث هذا الخطأ بغض النظر عما إذا كنت أستخدم نوعًا معينًا أو حرف بدل محدد أو حرف بدل غير محدود.هل هناك طريقة صحيحة أو اصطلاحية لتجاوز الطريقة غير العامة بدون تحذيرات وبدون استخدام @SuppressWarnings("unchecked")؟

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

المحلول

نعم، لديك للإعلان عن طريقة الرئيسي مع نفس التوقيع كما هو الحال في الفئة الأصل، دون إضافة أي معلومات الأدوية.

وأعتقد أن أفضل رهان هو لإضافة الشرح @SuppressWarnings("unchecked") إلى المعلمة من نوع الخام، وليس طريقة، حتى أنك لن سحق تحذيرات الأدوية الأخرى التي قد يكون في التعليمات البرمجية الخاصة بك.

نصائح أخرى

اجابة قصيرة:لا توجد طريقة للقيام بذلك.

إجابة غير مرضية:قم بتعطيل التحذيرات (المحددة) في IDE/build.xml الخاص بك.

إذا لم تتمكن من تغيير المكتبة، للأسف، عليك الالتزام بالطرق غير العامة.

تكمن المشكلة في أنه على الرغم من محو النوع، فإن كلا من init() لهما نفس التوقيع، إلا أنهما قد يكونان في الواقع طريقتين مختلفتين - أو نفس الشيء (*).لا يستطيع المترجم معرفة ما إذا كان يجب أن يقوم بالتجاوز أو التحميل الزائد، لذا فهو محظور.

(*) افترض أن مطور المكتبة يعني init (الخريطةu003CString,Integer> ).أنت الآن تقوم بتنفيذ init(Map<String,String>).يعد هذا تحميلًا زائدًا، ويجب وجود طريقتين في جدول vtable للفئة التابعة.

ولكن ماذا لو كان مطور المكتبة يقصد init(Map<String,String>)؟ثم إنه أمر متغلب، ويجب أن تكون طريقتك كذلك يستبدل init الأصلي في فئة الطفل، ولن يكون هناك سوى أسلوب واحد في جدول vtable الخاص بالطفل.

ملاحظة.أنا أكره الطريقة التي يتم بها تطبيق الأدوية العامة في Java :-(

وأعتقد فوق الجواب يعني القولSuppressWarnings ( "rawtypes") بدلا من ذلك.

لديك للإعلان عن الأسلوب مع نفس التوقيع باسم الأم، وبالتالي ستحصل تحذيرات عند ترجمة. يمكنك قمعها معSuppressWarnings ( "دون رادع")

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

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