यदि आप जावा में एक सामान्य वर्ग बनाते हैं (कक्षा में सामान्य प्रकार पैरामीटर हैं), क्या आप जेनेरिक तरीकों का उपयोग कर सकते हैं (विधि सामान्य प्रकार पैरामीटर लेती है)?जेनेरिक कक्षाओं में जावा जेनेरिक विधियां
public class MyClass {
public <K> K doSomething(K k){
return k;
}
}
public class MyGenericClass<T> {
public <K> K doSomething(K k){
return k;
}
public <K> List<K> makeSingletonList(K k){
return Collections.singletonList(k);
}
}
आप एक सामान्य विधि के साथ उम्मीद करेंगे के रूप में, मैं doSomething(K)
MyClass
के उदाहरण पर किसी भी वस्तु के साथ कॉल कर सकते हैं:
निम्नलिखित उदाहरण पर विचार
MyClass clazz = new MyClass();
String string = clazz.doSomething("String");
Integer integer = clazz.doSomething(1);
हालांकि, अगर मैं करने की कोशिश MyGenericClass
के उदाहरणों का उपयोग के बिना एक सामान्य प्रकार, निर्दिष्ट करते हुए मैं doSomething(K)
को Object
पर कॉल करता हूं, भले ही क्या K
में पारित किया गया था:
MyGenericClass untyped = new MyGenericClass();
// this doesn't compile - "Incompatible types. Required: String, Found: Object"
String string = untyped.doSomething("String");
अजीब तरह, यह करता है, तो वापसी प्रकार एक सामान्य वर्ग है संकलन करेगी - उदा List<K>
(वास्तव में, यह समझाया जा सकता है - नीचे उत्तर देखें): इसके अलावा
MyGenericClass untyped = new MyGenericClass();
List<String> list = untyped.makeSingletonList("String"); // this compiles
, यह भले ही वाइल्डकार्ड के साथ करता है, तो सामान्य वर्ग के लिखे जाने संकलन होगा,:
MyGenericClass<?> wildcard = new MyGenericClass();
String string = wildcard.doSomething("String"); // this compiles
है एक अच्छा कारण है कि एक untyped जेनेरिक वर्ग में एक सामान्य विधि बुला क्यों काम नहीं करना चाहिए?
क्या सामान्य वर्गों और जेनेरिक तरीकों से संबंधित कुछ चालाक चाल है जो मुझे याद आ रही है?
संपादित करें:
, स्पष्ट मैं एक untyped या कच्चे टाइप सामान्य वर्ग सामान्य वर्ग के प्रकार पैरामीटर (क्योंकि वे प्रदान की नहीं किया गया है) नहीं सम्मान करने के लिए उम्मीद करेंगे करने के लिए। हालांकि, यह मेरे लिए स्पष्ट नहीं है कि एक अवांछित या कच्ची टाइप वाली जेनेरिक कक्षा का अर्थ यह होगा कि सामान्य तरीकों को सम्मानित नहीं किया जाता है।
यह पारदर्शित करता है कि यह समस्या एसओ, सीएफ पर पहले से ही उठाई जा चुकी है। this question। इसका उत्तर यह बताता है कि जब एक वर्ग अपने कच्चे रूप में/सभी जेनरिक को क्लास से हटा दिया जाता है - जेनेरिक तरीकों के टाइपिंग सहित।
हालांकि, वास्तव में यह कोई स्पष्टीकरण नहीं है कि ऐसा क्यों है। तो मुझे अपने प्रश्न को स्पष्ट करने की अनुमति दें:
- जावा अनियमित या कच्चे प्रकार के सामान्य वर्गों पर जेनेरिक विधि टाइपिंग क्यों हटाता है? क्या इसके लिए कोई अच्छा कारण है, या यह सिर्फ एक निरीक्षण था?
संपादित करें - JLS की चर्चा:
यह सुझाव दिया है (यह सवाल पिछले तो सवाल करने के लिए और के जवाब में) है कि इस JLS 4.8 में व्यवहार किया जाता है, जिसमें कहा गया है:
एक कन्स्ट्रक्टर (§8.8) का प्रकार, उदाहरण विधि (§8.4, §9.4), या गैर स्थैतिक क्षेत्र (§8।3) एक कच्चे प्रकार सी कि अपनी सुपर-क्लास या superinterfaces से नहीं ली गई है एम कच्चे प्रकार है कि सी के लिए इसी सामान्य घोषणा में अपनी तरह का विलोपन से मेल खाती है है
यह मुझे कैसे इस के लिए स्पष्ट है एक untyped वर्ग से संबंधित है - कक्षा जेनेरिक प्रकार erasure प्रकार के साथ बदल दिया जाता है। यदि कक्षा जेनेरिक बाध्य हैं, तो मिटा प्रकार उन सीमाओं से मेल खाता है। यदि वे बाध्य नहीं हैं, तो मिटा प्रकार ऑब्जेक्ट है - उदा।
// unbound class types
public class MyGenericClass<T> {
public T doSomething(T t) { return t; }
}
MyGenericClass untyped = new MyGenericClass();
Object t = untyped.doSomething("String");
// bound class types
public class MyBoundedGenericClass<T extends Number> {
public T doSomething(T t) { return t; }
}
MyBoundedGenericClass bounded = new MyBoundedGenericClass();
Object t1 = bounded.doSomething("String"); // does not compile
Number t2 = bounded.doSomething(1); // does compile
जबकि सामान्य तरीकों उदाहरण तरीके हैं, यह मेरे लिए स्पष्ट नहीं है कि JLS 4.8 सामान्य तरीकों पर लागू होता है। जेनेरिक विधि का प्रकार (<K>
पहले उदाहरण में) untyped नहीं है, क्योंकि यह प्रकार विधि पैरामीटर द्वारा निर्धारित किया जाता है - केवल कक्षा untyped/raw-typed है।
[कच्चे प्रकार के संयोजन और जेनेरिक तरीके] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/11007723/combining-raw-types-and-generic-methods)। यह भी देखें: [यह सामान्य जावा कोड संकलित क्यों नहीं होगा?] (Http://stackoverflow.com/questions/662191/why-wont-this-generic-java-code-compile) –
http://stackoverflow.com/प्रश्न/14882003/जेनेरिक-शिकंजा-अप-गैर-संबंधित संग्रह/14882590 # 14882590 :) – Affe
@PaulBellora - धन्यवाद।पहला बहुत संबंधित है - हालांकि एसओ की मेरी अत्यधिक खोज इसे नहीं मिली, इसलिए संदर्भ के लिए धन्यवाद। दूसरा कम प्रासंगिक है, क्योंकि इसमें केवल सामान्य वर्ग शामिल हैं - जेनेरिक तरीकों से नहीं। – amaidment