2011-07-06 9 views
7

है, मैं एक सी # कोड के बराबर जावा कोड लिखना चाहता हूं।जावा: एक ऑब्जेक्ट बनाएं जिसका प्रकार एक प्रकार पैरामीटर

public abstract class A<T> where T : A<T>, new() 
{ 
    public static void Process() 
    { 
     Process(new T()); 
    } 

    public static void Process(T t) 
    { 
     // Do Something... 
    } 
} 

public class B : A<B> 
{ 
} 

public class C : A<C> 
{ 
} 

जावा मेरी कोड के बराबर इस तरह दिखता है:

मेरे सी # कोड इस प्रकार है।

public abstract class A<T extends A<T>> 
{ 
    public static <T extends A<T>> void process() 
    { 
     process(new T()); // Error: Cannot instantiate the type T 
    } 

    public static <T extends A<T>> void process(T t) 
    { 
     // Do Something... 
    } 

    public class B extends A<B> 
    { 
    } 

    public class C extends A<C> 
    { 
    } 
} 

यहाँ "नई()" व्युत्पन्न एक डिफ़ॉल्ट constructer जो आधार वर्ग से 'नई टी() "कॉल करने के लिए संभव बनाता है लिखने के लिए कक्षाएं वर्ग घोषणा बलों में वाक्य रचना। दूसरे शब्दों में जब मैं बेस क्लास को लिख रहा हूं, मुझे यकीन है कि व्युत्पन्न कक्षा में एक डिफ़ॉल्ट कन्स्ट्रक्टर होगा, ताकि मैं बेस क्लास से व्युत्पन्न क्लास ऑब्जेक्ट को तुरंत चालू कर सकूं।

जावा में मेरी समस्या है, मैं सुपर क्लास से व्युत्पन्न क्लास ऑब्जेक्ट को तुरंत चालू नहीं कर सकता। मुझे "new T()" कॉल के लिए त्रुटि मिलती है। क्या जावा में कोई सी # समान तरीका है या क्या मुझे प्रोटोटाइप पैटर्न और क्लोनिंग जैसे कुछ उपयोग करना चाहिए?

उत्तर

5

जावा reified generics का समर्थन नहीं करता है, इसलिए "new T();" के बराबर नहीं है। जिस तरह से मैं इसके आसपास काम करता हूं वह एक प्रकार के टोकन के खिलाफ प्रतिबिंब का उपयोग करना है। प्रकार टोकन इंगित करता है कि जेनेरिक प्रकार क्या है।

public abstract class A<T> { 
    private Class<T> typeToken; 
    // constructor 
    public A() { 
     typeToken = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 
    } 
} 

फिर वर्ग को तुरंत चालू करने के लिए प्रतिबिंब का उपयोग करें। यह बदसूरत है, लेकिन यह काम पूरा हो जाता है।

+0

त्वरित उत्तर के लिए धन्यवाद। चूंकि मैं एक स्थिर विधि के अंदर एक नया उदाहरण बनाने की कोशिश कर रहा हूं, इसलिए मैं getClass() कॉल नहीं कर सकता। टी। क्लास के अलावा संकलन-समय निर्माण का उपयोग नहीं किया गया है। तो, प्रतिबिंब मेरे लिए एक समाधान की तरह प्रतीत नहीं होता है। या मैं इसे अभी तक नहीं मिला (:।। –

+0

यह तभी उपवर्ग एक ठोस प्रकार पैरामीटर का उपयोग करता है काम करेंगे, तो उपवर्ग 'था सार्वजनिक वर्ग बी फैली एक ' उदाहरण के लिए, इस सटीक एक ही समस्या के लिए होता है मैं इसे खोजने प्रकार टोकन का उपयोग करने के लिए, लेकिन निर्माता या विधि में टोकन पारित करने के लिए फोन करने वाले की आवश्यकता के लिए बेहतर है। –

0

इसके अलावा, यदि आप जेनेरिक का उपयोग कर रहे हैं तो इससे सावधान रहें।

T[] someArray = new T[]; 

यह भी एक कारण सरणियों को ArrayList पसंद करते है। समस्या का कारण रेफिबिलिटी और टाइप एरर के साथ है।

2

आप this li nk - comparing java and C# generics से सी # और जावा में जेनेरिक के बीच अंतर का कुछ स्पष्टीकरण पा सकते हैं।

जावा जेनरिक एक पूरी तरह से संकलित समय निर्माण है। आप सामान्य प्रकार के पैरामीटर के साथ कुछ भी नहीं कर सकते हैं जो रनटाइम जानकारी पर किसी भी तरह से भरोसा करते हैं। इसमें शामिल हैं: सामान्य प्रकार मापदंडों के

  • बनाना उदाहरणों।
  • जेनेरिक प्रकार पैरामीटर के सरणी बनाना।
  • जेनेरिक प्रकार पैरामीटर के रनटाइम क्लास को क्वेरी करना।
  • जेनेरिक प्रकार पैरामीटर के साथ उदाहरण का उपयोग करना।

आप java.lang.reflect नामस्थान के साथ इस प्रतिबंध को बाईपास कर सकते हैं। उदाहरण के लिए इस stackoverflow प्रश्न देखें: Genercs and Class.forName()

0

बस बोग मानक सार फैक्टरी पैटर्न का उपयोग करें। फिर आपको अतिरिक्त लाभ मिलते हैं जिन्हें आप किसी विशिष्ट प्रकार पर नहीं लगा रहे हैं, कार्यान्वयन प्रकार के पास एक विशिष्ट कन्स्ट्रक्टर नहीं होना चाहिए, उदाहरण में कुछ पैरामीटरेशन हो सकते हैं, उदाहरण कैश किए जा सकते हैं, इत्यादि।

भगवान के प्यार के लिए, प्रतिबिंब का उपयोग न करें।

0

अन्य टिप्पणी के अलावा, मैं जेनरिक का उपयोग नहीं सुझाव है। उन्हें जरूरी नहीं है - वे संकलन समय पर फंस गए हैं - और यदि आप उन्हें अच्छी तरह से नहीं जानते हैं तो आप उन चीजों को करने की कोशिश करेंगे जो वे नहीं कर सकते हैं।

बार जब आप अपने वर्ग ठीक से काम कर, तो उन्हें वापस शामिल है। आपका आईडीई, उस बिंदु पर, आप उपयोगी और सुगम सलाह का एक बहुत दे देंगे, और जेनरिक आपको चेतावनी देता है जब आप की वस्तुओं का उपयोग करेगा गलत वर्ग

यह मेरे लिए संभव दिखता है कि इस वर्ग के समाप्त होने पर सभी को एक जेनरिक जरूरत नहीं होगी। (मुझे नहीं पता कि यह वर्ग और क्या कर सकता है, और मुझे स्थिर तरीकों के उपयोग को समझ में नहीं आता है - उन्हें किसी व्यक्तिगत इंस्टेंस की प्रकार की जानकारी तक कभी भी पहुंच नहीं होगी।)

0

असल में यह कोई समस्या नहीं है जावा। मुहावरे

public static <T extends A<T>> T process(Class<T> clazz) 
    { 
     T o = clazz.newInstance(); 
     process(o); 
     return o; 
    } 

    X x = process(X.class); // not too verbose 

मैंने सामान्य मामले को चित्रित करने के लिए एक वापसी मूल्य जोड़ा है।

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