لماذا لا يمكنني تمرير وسيطة النوع بشكل صريح إلى طريقة Java عامة؟

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

  •  09-06-2019
  •  | 
  •  

سؤال

لقد قمت بتعريف وظيفة Java:

static <T> List<T> createEmptyList() {
    return new ArrayList<T>();
}

إحدى طرق تسميتها هي كما يلي:

List<Integer> myList = createEmptyList(); // Compiles

لماذا لا يمكنني تسميتها من خلال تمرير وسيطة النوع العامة بشكل صريح؟:

Object myObject = createEmtpyList<Integer>(); // Doesn't compile. Why?

لقد فهمت الخطأ Illegal start of expression من المترجم.

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

المحلول

عندما لا يتمكن مترجم Java من استنتاج نوع المعلمة بنفسه لطريقة ثابتة، يمكنك دائمًا تمريرها باستخدام اسم الطريقة المؤهلة الكاملة:فصل .<النوع> الطريقة () ؛

Object list = Collections.<String> emptyList();

نصائح أخرى

يمكنك ذلك، إذا قمت بتمرير النوع كمعلمة أسلوب.

static <T> List<T> createEmptyList( Class<T> type ) {
  return new ArrayList<T>();
}

@Test
public void createStringList() {
  List<String> stringList = createEmptyList( String.class );
}

لا يمكن تعميم الأساليب بنفس الطريقة التي يمكن بها للنوع، لذا فإن الخيار الوحيد للأسلوب الذي يحتوي على نوع إرجاع عام مكتوب ديناميكيًا - أوه، هذا أمر بسيط :-) - هو تمرير النوع كوسيطة.

للحصول على أسئلة وأجوبة ممتازة حقًا حول أدوية Java، راجع الأسئلة الشائعة حول الأدوية العامة الخاصة بـ Angelika Langer.

.
.

متابعة:

لن يكون من المنطقي في هذا السياق استخدام وسيطة الصفيف كما في Collection.toArray( T[] ).السبب الوحيد لاستخدام المصفوفة هو أنه يتم استخدام نفس المصفوفة (المخصصة مسبقًا) لاحتواء النتائج (إذا كانت المصفوفة كبيرة بما يكفي لاستيعابها جميعًا).وهذا يوفر على تخصيص مصفوفة جديدة في وقت التشغيل طوال الوقت.

ومع ذلك، لأغراض التعليم، إذا كنت تريد استخدام كتابة المصفوفة، فإن بناء الجملة مشابه جدًا:

static <T> List<T> createEmptyList( T[] array ) {
  return new ArrayList<T>();
}

@Test
public void testThing() {
  List<Integer> integerList = createEmptyList( new Integer[ 1 ] );
}

لقد مر وقت طويل منذ أن بحثت في تلك الأجزاء من جافا، ولكن...

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

pauldoo نعم ، أنت على حق.إنها إحدى نقاط الضعف في أدوية جافا إيمهو.

أرد على Cheekysoft وأود أن أقترح أيضًا النظر في كيفية القيام بذلك بواسطة أشخاص Java أنفسهم، مثل T[] AbstractCollection#toArray(ت[] أ).أعتقد أن إصدار Cheekysofts متفوق، لكن إصدار Java يتمتع بميزة الألفة.

يحرر:تمت إضافة الرابط.إعادة التحرير:وجدت خطأ في SO :)


المتابعة على Cheekysoft:حسنًا، نظرًا لأنها قائمة من بعض الأنواع التي يجب إرجاعها، فيجب أن يبدو المثال المقابل كما يلي:

static <T> List<T> createEmptyList( List<T> a ) {
  return new ArrayList<T>();
}

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

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