2012-06-03 14 views
5

के लिए निम्न विधि का मान लेते हैं (जैसे अमरूद के Iterables से):पासिंग/एक समारोह के प्रकार पैरामीटर के साथ एक कक्षा लौटने

public static <T> Iterable<T> filter(final Iterable<?> unfiltered, final Class<T> type) { 
    return null; 
} 

और इस संग्रह:

Set<?> objs = ...; 

उसके बाद निम्न कोड को संकलित करता है और जेनिक्स सही ढंग से व्युत्पन्न

Iterable<String> a2 = Iterables.filter(objs, String.class); 

(गुवा में यह सभी स्ट्रिन का एक पुनरावर्तनीय वापस आ जाएगा ।

static class Abc<E> { 
    E someField; 
} 

मैं पता नहीं कैसे filter फोन और Iterable<Abc<?>> प्राप्त करने के लिए:

Iterable<Abc> a3 = Iterables.filter(objs, Abc.class); 
Iterable<Abc<?>> a4 = Iterables.filter(objs, Abc.class); // Compile error - Abc and Abc<?> are incompatible types 
Iterable<Abc<?>> a5 = Iterables.filter(objs, Abc<?>.class); // Compile error 
Iterable<Abc<?>> a6 = Iterables.<Abc<?>>filter(objs, Abc.class); // Compile error 
Iterable<Abc<?>> a7 = (Iterable<Abc<?>>) Iterables.filter(objs, Abc.class); // Compile error - inconvertible types 
Iterable<Abc<?>> a8 = Iterables.filter(objs, new Abc<?>().getClass()); // Compile error 
Iterable<Abc<?>> a8a = Iterables.filter(objs, new Abc<Object>().getClass()); // Compile error 

केवल a3 compiles, लेकिन फिर मैं objs में जी एस)

लेकिन अब निम्नलिखित वर्ग मान देता है एबीसी पर पैरामीटर नहीं है, और इस प्रकार बाद के कोड में कोई सामान्य प्रकार की जांच नहीं की जाती है।

मुझे पता है कि प्रकार पैरामीटर रनटाइम पर मौजूद नहीं हैं और इसलिए मैं लिखने के लिए atempt नहीं है कोड की तरह:

Iterable<Abc<String>> a9 = Iterables.filter(objs, Abc<String>.class); // Compile error 

मैं सिर्फ प्रकार एबीसी की सभी वस्तुओं फिल्टर करने के लिए (के रूप में a3 करता है) चाहते हैं, लेकिन परिणाम में जेनेरिक पैरामीटर है। ऐसा करने का एकमात्र तरीका मैंने पाया है, जो मूर्ख है:

Iterable<Abc<?>> a10 = new HashSet<Abc<?>>(); 
for (Abc<?> a : Iterables.filter(objs, Abc.class)) { 
    ((Set<Abc<?>>)a10).add(a); 
} 

धन्यवाद।

उत्तर

6

इस प्रश्न का कोई संतोषजनक उत्तर नहीं है। के साथ पैरामीटर के प्रकार के लिए कक्षा अक्षर, असंबद्ध वाइल्डकार्ड केवल सिद्धांत में काम करेंगे, हमारे पास अभी नहीं है।

आप Class<Abc<?>> -typed क्लास ऑब्जेक्ट को एक अनचेक कास्ट के साथ उत्पादित कर सकते हैं और इसे उपयोगिता विधि या फ़ील्ड में ले जा सकते हैं। जब तक Abc एस हैं, यह काफी अच्छी तरह से काम करता है।

@SuppressWarnings("unchecked") 
public static Class<Abc<?>> ABC = (Class<Abc<?>>)(Object) Abc.class; 
+0

मैं देखता हूं, लेकिन इसका मतलब है, मैं निम्न में से कोई भी निम्नलिखित कर सकता हूं: 'Iterable > a1 = Iterables.filter (this.getObjects(), (कक्षा >) (ऑब्जेक्ट) Abc.class);' 'Iterable > a2 = (Iterable >) (ऑब्जेक्ट) Iterables.filter (this.getObjects(), Abc.class); ' यह बदसूरत है लेकिन यह काम करता है। – Jirka

+0

@ जिर्का-एक्स 1 हां, इनलाइनों को भी रेखांकित करना। केवल नकारात्मक पक्ष यह है कि चेतावनी दबाने से कम स्थानीय होता है। –

0

मैंने पाया इस संकलित ..

public static <T> Iterable<Abc<T>> myFilter (Iterable<Abc<T>> myIterator) { 
    Class<Abc<T>> myClass = null; 
    Iterable<Abc<T>> a3 = Iterables.filter(myIterator, myClass); 
    return a3; 
} 

लेकिन यह सिर्फ myFilter() के फोन करने वाले के लिए ऊपर एक ही समस्या से चलता है। मुझे संदेह है कि Ben Schulz सही जवाब है।

+1

यह संकलित करता है, लेकिन 'myclass' चर में कोई सामग्री नहीं है। लेकिन मैं सुझाए गए विधि का उपयोग कर सकता हूं: '(एबीसी ) (ऑब्जेक्ट) Abc.class' इसे असाइन करने के लिए। – Jirka

संबंधित मुद्दे