जावा जेनरिक टी बनाम वस्तु


127

मैं सोच रहा था कि निम्नलिखित दो विधि घोषणाओं में क्या अंतर है:

public Object doSomething(Object obj) {....}

public <T> T doSomething(T t) {....}

क्या ऐसा कुछ है जो आप कर सकते हैं / एक के साथ करेंगे लेकिन दूसरे के साथ नहीं? मुझे इस साइट पर यह प्रश्न कहीं और नहीं मिला।

जवाबों:


112

संदर्भ से अलग - कोई अंतर नहीं। दोनों पर 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रनटाइम पर एक , होगा ।

14

यहां अंतर यह है कि पहले में, हम निर्दिष्ट करते हैं कि कॉलर को ऑब्जेक्ट इंस्टेंस (किसी भी वर्ग) को पास करना होगा, और इसे एक अन्य ऑब्जेक्ट (किसी भी वर्ग, जरूरी नहीं कि उसी प्रकार का) वापस मिल जाएगा।

दूसरे में, लौटा हुआ प्रकार उसी प्रकार का होगा जैसा कि तब दिया गया था जब कक्षा को परिभाषित किया गया था।

Example ex = new Example<Integer>();

यहां हम निर्दिष्ट करते हैं कि किस प्रकार का टी होगा जो हमें एक वर्ग या विधि पर अधिक बाधाओं को लागू करने की अनुमति देता है। उदाहरण के लिए हम LinkedList<Integer>या तो एक पल को रोक सकते हैं LinkedList<Example>और हम जानते हैं कि जब हम इनमें से किसी एक तरीके को कहते हैं, तो हमें एक इंटेगर या उदाहरण का उदाहरण मिलेगा।

यहां मुख्य लक्ष्य यह है कि कॉलिंग कोड यह निर्दिष्ट कर सकता है कि इसे लागू करने के लिए टाइप-कास्टिंग पर निर्भर होने के बजाय एक वर्ग किस प्रकार की वस्तुओं पर काम करेगा।

Oracle से जावा जेनेरिक * देखें ।

* अपडेट किया गया।


13

अंतर यह है कि सामान्य तरीकों से मुझे कास्ट करने की आवश्यकता नहीं है और जब मैं गलत करता हूं तो मुझे एक संकलन त्रुटि मिलती है:

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;
    }
}

जैसा कि आप उल्लेख करने की जरूरत नहीं है कि वस्तुओं को अब और भी नहीं डालना है, जैसा कि एंड्रॉइड 6.
जॉन लॉर्ड

2

आपको अतिरिक्त क्लास कास्टिंग करने की आवश्यकता नहीं है। पहले मामले में आपको हमेशा क्लास java.lang का एक ऑब्जेक्ट मिलेगा। जिस विषय को आपको अपनी कक्षा में डालना होगा। दूसरे मामले में T को जेनेरिक हस्ताक्षर में परिभाषित वर्ग के साथ बदल दिया जाएगा और किसी वर्ग की कास्टिंग की आवश्यकता नहीं होगी।


2

रनटाइम में, कुछ भी नहीं। लेकिन संकलित समय पर दूसरा यह सुनिश्चित करने के लिए प्रकार की जाँच करेगा कि पैरामीटर का प्रकार और वापसी मान मिलान का प्रकार (या उपप्रकार) जो भी प्रकार T को हल करता है (पहला उदाहरण भी प्रकार की जाँच करता है लेकिन हर वस्तु एक है वस्तु का उपप्रकार इसलिए प्रत्येक प्रकार स्वीकार किया जाएगा)।


2

T एक सामान्य प्रकार है। मतलब इसे रनटाइम पर किसी भी क्वालिफाइंग ऑब्जेक्ट द्वारा प्रतिस्थापित किया जा सकता है। आप इस तरह की एक विधि को लागू कर सकते हैं:

String response = doSomething("hello world");

या

MyObject response = doSomething(new MyObject());

या

Integer response = doSomething(31);

जैसा कि आप देख सकते हैं, यहां बहुरूपता है।

लेकिन अगर यह ऑब्जेक्ट वापस करने के लिए घोषित किया जाता है, तो आप ऐसा तब तक नहीं कर सकते जब तक आप चीजों को टाइप नहीं करते।


क्या हम कह सकते हैं कि <T>कोई ऑटोबॉक्सिंग नहीं है?
SMUsamaShah

0

पहले मामले में यह किसी भी प्रकार के पैरामीटर लेता है जैसे एस्ट्रिंग और एक प्रकार का फू लौटाता है। दूसरे मामले में यह प्रकार foo का एक पैरामीटर लेता है और प्रकार foo की एक वस्तु लौटाता है।


0

कुछ कारण हैं जो आप जावा में ऑब्जेक्ट प्रकार पर पीढ़ी मान सकते हैं:

  1. जेनेरिक लचीला और सुरक्षित है। उसी समय, ऑब्जेक्ट के साथ काम करना जिसमें टाइप-कास्टिंग की आवश्यकता होती है, त्रुटि-प्रवण है
  2. Java में टाइपिंग स्लो है Ref: [1]: https://www.infoworld.com/article/2076555/java-performance-programming--part-2--the-cost-of-casting.html
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.