मैं जावा जेनेरिक और varargs का उपयोग कर रहा हूँ।varCs और जेनेरिक का उपयोग करते समय ClassCastException
यदि मैं निम्नलिखित कोड का उपयोग करता हूं, तो मुझे ClassCastException
मिलेगा, भले ही मैं कास्ट का उपयोग नहीं कर रहा हूं।
स्ट्रेंजर अभी तक, अगर मैं इसे एंड्रॉइड (दल्विक) पर चलाता हूं तो कोई स्टैक ट्रेस अपवाद के साथ शामिल नहीं है, और यदि मैं इंटरफ़ेस को अमूर्त वर्ग में बदलता हूं, तो अपवाद चर e
खाली है।
कोड:
public class GenericsTest {
public class Task<T> {
public void doStuff(T param, Callback<T> callback) {
// This gets called, param is String "importantStuff"
// Working workaround:
//T[] arr = (T[]) Array.newInstance(param.getClass(), 1);
//arr[0] = param;
//callback.stuffDone(arr);
// WARNING: Type safety: A generic array of T is created for a varargs parameter
callback.stuffDone(param);
}
}
public interface Callback<T> {
// WARNING: Type safety: Potential heap pollution via varargs parameter params
public void stuffDone(T... params);
}
public void run() {
Task<String> task = new Task<String>();
try {
task.doStuff("importantStuff", new Callback<String>() {
public void stuffDone(String... params) {
// This never gets called
System.out.println(params);
}});
} catch (ClassCastException e) {
// e contains "java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;"
System.out.println(e.toString());
}
}
public static void main(String[] args) {
new GenericsTest().run();
}
}
आप इस चलाते हैं, तो आप एक ClassCastException
कि Object
स्टैक ट्रेस अमान्य पंक्ति संख्या की ओर इशारा करते के साथ String
में ढाला नहीं जा सकता है मिलेगा। क्या यह जावा में एक बग है? मैंने इसे जावा 7 और एंड्रॉइड एपीआई 8 में परीक्षण किया है। मैंने इसके लिए कामकाज किया (doStuff
-method में टिप्पणी की), लेकिन ऐसा लगता है कि इसे इस तरह से करना है। अगर मैं varargs (T...
) हटा देता हूं, तो सब कुछ ठीक काम करता है, लेकिन मेरे वास्तविक कार्यान्वयन को इसकी आवश्यकता है। अपवाद से
स्टैकट्रेस है:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at GenericsTest$1.stuffDone(GenericsTest.java:1)
at GenericsTest$Task.doStuff(GenericsTest.java:14)
at GenericsTest.run(GenericsTest.java:26)
at GenericsTest.main(GenericsTest.java:39)
है कि आपको स्टैकट्रेस की एक प्रति प्रदान कर सकता है। मेरा संदेह यह है कि यह अंतर्निहित कलाकारों से है जो टाइप एरर के कारण होता है। – Matt
प्रश्न में स्टैक ट्रेस जोड़ा गया। – murgo