كيفية إنشاء فئة حرفية من نوع معروف: الفئة >

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

  •  19-09-2019
  •  | 
  •  

سؤال

اتخذ ما يلي:

public Class<List<String>> getObjectType() {
    // what can I return here?
}

ما التعبير الحرفي من الدرجة التي يمكنني العودة من هذه الطريقة التي سوف تلبي الأجيال وتجميعها؟ List.class لن تجميع، ولا سوف List.<String>class.

إذا كنت تتساءل "لماذا"، فأنا أكتب تنفيذ الربيع FactoryBean<List<String>>, ، والتي تتطلب مني تنفيذ Class<List<String>> getObjectType(). وبعد ومع ذلك، هذا هو ليس سؤال الربيع.

تعديل: سمعت صرختي البيئة من قبل القوى التي تكون في Springsource، وهكذا سيكون لربيع 3.0.1 نوع العودة getObjectType() تغير إلى Class<?>, ، والتي تتجنب المشكلة بدقة.

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

المحلول

يمكنك دائما وضعها على ما تحتاجه، مثل هذا

return (Class<List<String>>) new ArrayList<String>().getClass();

أو

return (Class<List<String>>) Collections.<String>emptyList().getClass();

لكنني أفترض أن هذا ليس ما أنت عليه. حسنا، إنه يعمل، مع تحذير، لكنه ليس بالضبط "جميل".

أنا فقط وجدت هذا

لماذا لا يوجد فئة حرفية لأنواع البدل المعلمة؟

نظرا لأن النوع المعلمات البدل لا يحتوي على تمثيل نوع وقت التشغيل الدقيق.

لذلك قد يكون الصب هو السبيل الوحيد للذهاب.

نصائح أخرى

يجب ألا تستخدم البنية Class<List<String>>. وبعد إنه لا معنى له، وينبغي أن ينتج عنه تحذير في جافا (ولكن لا). مثيلات الطبقة تمثل دائما أنواع خام، حتى تتمكن من الحصول عليها Class<List>; ؛ هذا هو. إذا كنت تريد شيئا ما تمثل نوع عام تم تجديده مثل List<String>, ، تحتاج إلى "الرمز المميز من نوع السوبر" مثل استخدامات الغيار:

http://google-guice.googlecode.com/git/javadoc/com/google/inject/typeliteral.html.

وجود أ Class<List<String>> خطير بطبيعته. إليك لماذا:

// This statement generates a warning - for a reason...
Class<List<String>> unsafeListClass = (Class<List<String>>) (Class<?>) List.class;

List<Integer> integerList = new ArrayList<Integer>(); // Ok
integerList.add(42); // Ok

System.out.println(unsafeListClass.isInstance(integerList)); // Prints "true".
List<String> stringList =
   unsafeListClass.cast(integerList); // Succeeds, with no warning!
stringList.add("Hello, World!"); // Also succeeds with no warning

for (int x: integerList) {
    // Compiles without warning, but throws ClassCastException at runtime
    System.out.println(100-x);
}

وجد هذا الرابط على SpringFrameWork.org الذي يعطي بعض البصيرة.

على سبيل المثال

List<String> myList = new ArrayList<String>();
return (Class<List<String>>)myList.getClass();

يمكنك تنفيذ هذه الطريقة مثل هذا:

public Class<List<String>> getObjectType() {
    return (Class<List<String>>) ((Class)List.class);
}

تحقق من هذه المناقشة على منتديات الشمس:

http://forums.sun.com/thread.jspa؟threadid=5253007.

وشركة المدونة المرجعية التي تصف عمل حولها باستخدام "الرموز الفائقة":

http://gafter.blogspot.com/2006/12/super-type-tokens.html.

لست متأكدا مما إذا كان ذلك ممكنا على الإطلاق، نظرا لأن أي فئة حرفية سيتم تجميعها ل Class.forName(...) وبما أن هذا يحدث في وقت التشغيل لا توجد معلومات عامة اليسار.

لست متأكدا، لكن السؤال التالي الذي سألت قد تكون ذات صلة بك ...

Java Generics نوع المعلمات والعمليات على هذه الأنواع

ماذا عن هذا:

public class TestMain {
    public static void main(String[] args) throws Exception {
        Type type = TestMain.class.getMethod("dummy").getGenericReturnType();
        System.out.println("type = " + type);
    }

    public List<Integer> dummy() {return null;}
}

هذه المطبوعات:

type = java.util.List<java.lang.Integer>

النهج التالي هو مشكلة:

> public Class<List<String>> getModelType() {
>   return (Class<List<String>>) new ArrayList<String>().getClass();
> }

على سبيل المثال إذا كنت ترغب في اختبار ما إذا كان كائن يقول من النوع

org.eclipse.emf.common.util.BasicEList<String> 

هو من النوع

List<String> 

بناء على نتيجة نهج GetModelType المذكور أعلاه، على سبيل المثال:

BasicEList<String> fromObject = ...;
if (getModelType().isAssignableFrom(fromObject.getClass())) {
    transferFromModelToUi(getModelType().cast(fromObject));
}

سيؤدي ذلك إلى خطأ في حين أنه يجب أن يكون صحيحا لأن كلا الكائنات تنفذ قائمة الواجهة (نظرا لأن GetModeltype () إرجاع كائن فئة قائمة من النوع وليس ArrayList).

فيما يلي نهج يعمل بالنسبة لي (مرهقة قليلا ولكن يؤدي إلى تصحيح النتائج في المثال أعلاه، يمكن نقله إلى تهيئة ثابتة):

public Class<List<String>> getModelType() {
    Class<?> arrayListClass = new ArrayList<String>().getClass();
    Class<?>[] interfaces = arrayListClass.getInterfaces();
    int index = 0;
    for (int i = 0; i < interfaces.length; i++) {
        if (interfaces[i].equals(List.class)) {
            index = i;
            break;
        }
    }
    return (Class<List<String>>) interfaces[index];
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top