سؤال

لنفترض أن لدي الفصل التالي:

public class Test<E> {
    public boolean sameClassAs(Object o) {
        // TODO help!
    }
}

كيف يمكنني التحقق من ذلك o هو نفس الفئة كما E?

Test<String> test = new Test<String>();
test.sameClassAs("a string"); // returns true;
test.sameClassAs(4); // returns false;

لا أستطيع تغيير توقيع الطريقة من (Object o) لأنني أتجاوز فئة فائقة وبالتالي لا يمكنني اختيار توقيع الطريقة الخاصة بي.

أفضل أيضًا عدم السير في طريق محاولة الإدلاء ثم التقاط الاستثناء الناتج في حالة فشله.

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

المحلول

مثال على Test ليس لديه معلومات عن ماذا E في وقت التشغيل.لذلك، تحتاج إلى تمرير أ Class<E> إلى منشئ الاختبار.

public class Test<E> {
    private final Class<E> clazz;
    public Test(Class<E> clazz) {
        if (clazz == null) {
            throw new NullPointerException();
        }
        this.clazz = clazz;
    }
    // To make things easier on clients:
    public static <T> Test<T> create(Class<T> clazz) {
        return new Test<T>(clazz);
    }
    public boolean sameClassAs(Object o) {
        return o != null && o.getClass() == clazz;
    }
}

إذا كنت تريد علاقة "مثيل"، فاستخدم Class.isAssignableFrom بدلا من ال Class مقارنة.ملحوظة، E يجب أن يكون نوعًا غير عام لنفس السبب Test يحتاج إلى Class هدف.

للحصول على أمثلة في Java API، راجع java.util.Collections.checkedSet وما شابه ذلك.

نصائح أخرى

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

public class Test<E> {
    private Class<E> clazz;
    public Test(Class<E> clazz) {
       this.clazz = clazz;
    }
    public boolean sameClassAs(Object o) {
        return this.clazz.isInstance(o);
    }
}

يمكنني فقط أن أجعل الأمر يعمل على النحو التالي:

public class Test<E> {  

    private E e;  

    public void setE(E e) {  
        this.e = e;  
    }

    public boolean sameClassAs(Object o) {  

        return (o.getClass().equals(e.getClass()));  
    }

    public boolean sameClassAs2(Object o) {  
        return e.getClass().isInstance(o);  
    }
}

كنت أحاول فقط أن أفعل نفس الشيء، وإحدى الحيل الرائعة التي أدركتها للتو هي أنه يمكنك تجربة طاقم التمثيل، وإذا فشل طاقم الممثلين، فسيتم طرح ClassCastException.يمكنك التقاط ذلك، والقيام بأي شيء.

لذلك يجب أن تبدو طريقة SameClassAs الخاصة بك كما يلي:

public boolean sameClassAs(Object o) {
    boolean same = false;
    try {
        E t = (E)o;
        same = true;
    } catch (ClassCastException e) {
        // same is false, nothing else to do
    } finally {
        return same;
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top