जवाबों:
संदर्भ से अलग - कोई अंतर नहीं। दोनों पर t
और obj
आप केवल के तरीकों को लागू कर सकते हैं Object
।
लेकिन संदर्भ के साथ - यदि आपके पास एक सामान्य वर्ग है:
MyClass<Foo> my = new MyClass<Foo>();
Foo foo = new Foo();
फिर:
Foo newFoo = my.doSomething(foo);
वस्तु के साथ समान कोड
Foo newFoo = (Foo) my.doSomething(foo);
दो फायदे:
Object
संस्करण का उपयोग किया जाता है, तो आप सुनिश्चित नहीं होंगे कि विधि हमेशा वापस आती है Foo
। यदि यह वापस आता है Bar
, तो आपके पास ClassCastException
रनटाइम पर एक , होगा ।यहां अंतर यह है कि पहले में, हम निर्दिष्ट करते हैं कि कॉलर को ऑब्जेक्ट इंस्टेंस (किसी भी वर्ग) को पास करना होगा, और इसे एक अन्य ऑब्जेक्ट (किसी भी वर्ग, जरूरी नहीं कि उसी प्रकार का) वापस मिल जाएगा।
दूसरे में, लौटा हुआ प्रकार उसी प्रकार का होगा जैसा कि तब दिया गया था जब कक्षा को परिभाषित किया गया था।
Example ex = new Example<Integer>();
यहां हम निर्दिष्ट करते हैं कि किस प्रकार का टी होगा जो हमें एक वर्ग या विधि पर अधिक बाधाओं को लागू करने की अनुमति देता है। उदाहरण के लिए हम LinkedList<Integer>
या तो एक पल को रोक सकते हैं LinkedList<Example>
और हम जानते हैं कि जब हम इनमें से किसी एक तरीके को कहते हैं, तो हमें एक इंटेगर या उदाहरण का उदाहरण मिलेगा।
यहां मुख्य लक्ष्य यह है कि कॉलिंग कोड यह निर्दिष्ट कर सकता है कि इसे लागू करने के लिए टाइप-कास्टिंग पर निर्भर होने के बजाय एक वर्ग किस प्रकार की वस्तुओं पर काम करेगा।
Oracle से जावा जेनेरिक * देखें ।
* अपडेट किया गया।
अंतर यह है कि सामान्य तरीकों से मुझे कास्ट करने की आवश्यकता नहीं है और जब मैं गलत करता हूं तो मुझे एक संकलन त्रुटि मिलती है:
public class App {
public static void main(String[] args) {
String s = process("vv");
String b = process(new Object()); // Compilation error
}
public static <T> T process(T val) {
return val;
}
}
ऑब्जेक्ट का उपयोग करने के लिए मुझे हमेशा कास्ट करने की आवश्यकता होती है और गलत होने पर मुझे कोई त्रुटि नहीं मिलती है:
public class App {
public static void main(String[] args) {
String s = (String)process("vv");
String b = (String)process(new Object());
}
public static Object process(Object val) {
return val;
}
}
आपको अतिरिक्त क्लास कास्टिंग करने की आवश्यकता नहीं है। पहले मामले में आपको हमेशा क्लास java.lang का एक ऑब्जेक्ट मिलेगा। जिस विषय को आपको अपनी कक्षा में डालना होगा। दूसरे मामले में T को जेनेरिक हस्ताक्षर में परिभाषित वर्ग के साथ बदल दिया जाएगा और किसी वर्ग की कास्टिंग की आवश्यकता नहीं होगी।
रनटाइम में, कुछ भी नहीं। लेकिन संकलित समय पर दूसरा यह सुनिश्चित करने के लिए प्रकार की जाँच करेगा कि पैरामीटर का प्रकार और वापसी मान मिलान का प्रकार (या उपप्रकार) जो भी प्रकार T को हल करता है (पहला उदाहरण भी प्रकार की जाँच करता है लेकिन हर वस्तु एक है वस्तु का उपप्रकार इसलिए प्रत्येक प्रकार स्वीकार किया जाएगा)।
T एक सामान्य प्रकार है। मतलब इसे रनटाइम पर किसी भी क्वालिफाइंग ऑब्जेक्ट द्वारा प्रतिस्थापित किया जा सकता है। आप इस तरह की एक विधि को लागू कर सकते हैं:
String response = doSomething("hello world");
या
MyObject response = doSomething(new MyObject());
या
Integer response = doSomething(31);
जैसा कि आप देख सकते हैं, यहां बहुरूपता है।
लेकिन अगर यह ऑब्जेक्ट वापस करने के लिए घोषित किया जाता है, तो आप ऐसा तब तक नहीं कर सकते जब तक आप चीजों को टाइप नहीं करते।
<T>
कोई ऑटोबॉक्सिंग नहीं है?
पहले मामले में यह किसी भी प्रकार के पैरामीटर लेता है जैसे एस्ट्रिंग और एक प्रकार का फू लौटाता है। दूसरे मामले में यह प्रकार foo का एक पैरामीटर लेता है और प्रकार foo की एक वस्तु लौटाता है।
कुछ कारण हैं जो आप जावा में ऑब्जेक्ट प्रकार पर पीढ़ी मान सकते हैं: