C ++ में टाइप किए गए कीवर्ड के लिए जावा समकक्ष या कार्यप्रणाली है?


244

C और C ++ बैकग्राउंड से आने पर, मुझे typedefअविश्वसनीय रूप से मददगार होने का विवेकपूर्ण उपयोग मिला । क्या आप जावा में समान कार्यक्षमता प्राप्त करने के तरीके के बारे में जानते हैं, चाहे वह जावा तंत्र हो, पैटर्न हो, या आपके द्वारा उपयोग किए गए कुछ अन्य प्रभावी तरीके हों?


6
टाइपडीफ का उपयोग किया जा सकता है या बहुत सी चीजें, अच्छे और बुरे, हालांकि हर कोई इस बात से सहमत नहीं है कि कौन सा है। क्या आप कहेंगे कि आपको लगता है कि टाइपडेफ के कौन से पहलू मूल्यवान हैं? इस तरह हम आपको बता सकते हैं कि जावा में समान प्रभाव कैसे प्राप्त करें या यह कुछ ऐसा क्यों है जो आप जावा में नहीं करना चाहते हैं। प्रत्येक अनुमान के नीचे दिए गए उत्तरों का संग्रह आप लेखक के पसंदीदा (या सबसे अधिक नफरत) उपयोग के बारे में बात कर रहे हैं।
PanCrit

3
अगर मैं बाद में इसे कक्षा में बदल सकता हूं तो मुझे देशी प्रकार लिखना पसंद है। typedef indexT int; उदाहरण के लिए। बाद में, यदि मैं इंडेक्सटी को एक वर्ग बनाना चाहता हूं, तो मैं इसे लागू करता हूं और टंकण को ​​हटा देता हूं। यह जानकारी छिपाने में मदद करता है।
जेआर लॉरहॉर्न


1
मुझे यकीन नहीं है कि इस के डाउनसाइड्स क्या हैं, लेकिन:public interface ScopeFactory { <Scope extends Map<String, Object>> Scope create(...) throws Exception; }
स्कूटी पफ

जवाबों:


112

जावा में आदिम प्रकार, वस्तुएं और सरणियाँ हैं और यही है। कोई टाइपफ़ीड नहीं।


38
मुझे लगता है कि ज्यादातर लोग typedefइसे फिर booleanसे परिभाषित करना चाहते हैं bool
टॉम ज़ातो -

66
@ TomášZato मैं ज्यादातर लोगों को नहीं जानता, लेकिन मेरे अनुभव में, यह शब्दार्थ जोड़ने के लिए उपयोगी है: typedef int PlayerIDजो संकलक को यह सुनिश्चित करने में सक्षम बनाता है कि प्लेयरआईडीएस का अन्य जातियों के साथ परस्पर उपयोग नहीं किया जा रहा है, और यह कोड को मनुष्यों के लिए और भी अधिक उपयोगी बनाता है। । मूल रूप से, यह एक एनम की तरह है लेकिन मूल्यों के एक सीमित सेट के बिना।
weberc2

76
@ TomášZato यह लंबे प्रकार को छोटा करने के लिए भी उपयोगी है typedef MegaLongTemplateClass<With, Many, Params> IsShorten;
एलेक्स मेडवशेक

32
@ weberc2 "जो संकलक को यह सुनिश्चित करने में सक्षम बनाता है कि प्लेयरआईडी का अन्य स्थानों के साथ परस्पर उपयोग नहीं किया जा रहा है" - typedefऐसी किसी भी चीज को सक्षम नहीं करता है। यह सिर्फ एक प्रकार का दूसरा नाम देता है।
इमलाई

7
उदाहरण के लिए, उपयोगी होने पर, आपके पास कुछ प्रकार की आईडी होती है intऔर आपको इसे बदलने की आवश्यकता होती है long, आपको इसे कोड में हर उस स्थान पर बदलना होगा जहां आप आईडी के साथ काम करते हैं। यदि आपके पास था typedef, तो आपको इसे केवल 1 स्थान पर बदलना होगा।
जरदो

101

यदि यह आपका मतलब है, तो आप बस उस वर्ग का विस्तार कर सकते हैं जिसे आप टाइप करना चाहते हैं, जैसे:

public class MyMap extends HashMap<String, String> {}

5
मैं तर्क दूंगा कि क्या यह सी में टाइपडिफ का उपयोग करने की तुलना में कोई अधिक विरोधी पैटर्न है
जेड

22
यह निश्चित रूप से है - typedefउन फर्जी वर्गों के लिए लेख का वर्णन करने वाली समस्याओं में से कोई भी नहीं है (और वे बहुत वास्तविक हैं)।
पावेल मिनाएव

30
@Andreas_D: अपने लिंक, फिक्स्ड: ibm.com/developerworks/java/library/j-jtp02216/index.html
जानूस Troelsen

7
मुझे यह पसंद है उसी कारण से मुझे टाइपडेफ पसंद है। यदि आपके पास वस्तुओं का एक कंटेनर है, तो टाइपडिफ को बदलकर कंटेनर प्रकारों को स्वैप करना आसान है। इसके अलावा, यह कंटेनर को अंतिम उपयोगकर्ता को सार कर सकता है (जो कभी-कभी वांछनीय होता है)। मैं आमतौर पर किसी अन्य वर्ग के अंदर ऐसा करता हूं, इसलिए तब प्रकार अधिक स्पष्ट हो जाता है (यानी MyTree.Branches, जहां कक्षा शाखाएं HashSet <MyTree> {})
जोश पेटिट

8
हालांकि इस दृष्टिकोण के साथ मुख्य समस्या यह है कि आप इसे finalकक्षाओं के साथ उपयोग नहीं कर सकते हैं।
AJMansfield

14

1.6 के रूप में जावा में कोई टाइपफ़ीड नहीं है, आप क्या कर सकते हैं जो आप चाहते हैं उसके लिए एक आवरण वर्ग बना सकते हैं क्योंकि आप अंतिम कक्षाओं (पूर्णांक, डबल, आदि) को उपवर्ग नहीं कर सकते हैं


3
संदर्भित एंटी-पैटर्न लेख इस धारणा पर आधारित है कि आप बस अपनी टाइपिंग को छोटा करना चाहते हैं (जो वास्तव में सहायक प्रकार की जानकारी को छिपाएगा)। अधिकांश लोग जो चाहते हैं, उसका वास्तविक उपयोग प्रकारों की अवहेलना करना है और संकलक को अपना काम करने देना है। ऊपर इंडेक्स देखें। सार्वजनिक चालान fetchInvoiceItem (स्ट्रिंग, स्ट्रिंग, स्ट्रिंग); बनाम पब्लिक इनवॉइस fetchInvoiceItem (CustomerId, InvoiceId, InvoiceLineItemId); स्पष्ट प्रकार के प्लस कन्वर्टर्स / वैलिडेटर्स प्रोग्रामिंग वेब एपीआई बनाते हैं जहां हर चीज एक बहुत अधिक सुरक्षित के रूप में शुरू होती है।
एंगलबार्ट'

कोई ऑपरेटर जावा में oveloading, तो यह बदसूरत हो जाता है
mils

9

जैसा कि दूसरों ने पहले भी उल्लेख किया है,
जावा में कोई टाइप किए गए तंत्र नहीं है।
मैं भी सामान्य रूप से "नकली वर्गों" का समर्थन नहीं करता हूं, लेकिन यहां अंगूठे का एक सामान्य सख्त नियम नहीं होना चाहिए:
यदि उदाहरण के लिए आपका कोड उदाहरण के लिए "जेनेरिक आधारित प्रकार" से अधिक का उपयोग करता है:

Map<String, List<Integer>> 

आपको निश्चित रूप से उस उद्देश्य के लिए एक उपवर्ग होने पर विचार करना चाहिए।
एक अन्य दृष्टिकोण जिस पर विचार कर सकते हैं, उदाहरण के लिए आपके कोड में एक मंदी है जैसे:

//@Alias Map<String, List<Integer>>  NameToNumbers;

और फिर अपने कोड NameToNumbers में उपयोग करें और प्रासंगिक जावा कोड को संसाधित और उत्पन्न करने के लिए एक पूर्व संकलक कार्य (ANT / ग्रेडल / मावेन) है।
मुझे पता है कि इस उत्तर के कुछ पाठकों को यह अजीब लग सकता है, लेकिन यह है कि जेडडीके 5 से पहले "एनोटेशन" को लागू करने के लिए कई रूपरेखाओं को लागू किया गया है, यह परियोजना लोमबॉक और अन्य रूपरेखाएं हैं।


5

वास्तव में, जैवलैंड को टाइप करने वाली टाइफेड का एकमात्र उपयोग अलियासिंग है- यानी, एक ही वर्ग को कई नाम दे रहा है। यही है, आपको एक वर्ग "ए" मिला है और आप उसी चीज को संदर्भित करने के लिए "बी" चाहते हैं। C ++ में, आप "typedef BA?" कर रहे होंगे

दुर्भाग्य से, वे इसका समर्थन नहीं करते हैं। हालाँकि, यदि आप इसमें शामिल सभी प्रकारों को नियंत्रित करते हैं, तो आप लाइब्रेरी स्तर पर एक बुरा हैक खींच सकते हैं- या तो आप A से B का विस्तार करते हैं या B का खाता सुरक्षित करते हैं।


14
बीत रहा है typedefभी सामान्य प्रकार के आमंत्रण के लिए अन्य नाम बना करने के लिए उपयोगी होगा। उदाहरण के लिए: typedef A<Long,String> B;(यह एक विशेष मामला हो सकता है कि आपने क्या वर्णन किया है, लेकिन यह विचार की अपील को और अधिक स्पष्ट रूप से दर्शाता है)।
दोपहर 12:24

अपने उपयोग के मामले में, मैं आदिम प्रकार के उपनाम देना चाहता हूं। real_tके लिए doubleऔर के boolलिए boolean
एरोन फ्रेंके

3

शायद यह एक और संभावित जगह हो सकती है:

@Data
public class MyMap {
    @Delegate //lombok
    private HashMap<String, String> value;
}

2
क्या आपको नहीं लगता कि अब इसमें कोई समस्या है क्योंकि जब भी आप myMapटाइप के उदाहरण को परिभाषित MyMapकरते हैं, तो आप केवल टाइप myMapInstance.value.SomeOperation()करने के बजाय वास्तविक हैशपॉप पर काम कर सकते हैं myMapInstance.SomeOperation()। यह गुस्सा है, है ना?
पारा 0114 22

2
आप अभी भी myMapInstance.SomeOperation () कर सकते हैं - यह @Delegate के लिए क्या है
shrewquest

3

जैसा कि अन्य उत्तरों में उल्लेख किया गया है, आपको छद्म-टाइपफेट एंटीपैटर्न से बचना चाहिए । हालाँकि, टाइपराइफ़ अभी भी उपयोगी हैं, भले ही वह उन्हें प्राप्त करने का तरीका न हो। आप विभिन्न सार प्रकारों के बीच अंतर करना चाहते हैं जिनमें एक ही जावा प्रतिनिधित्व है। आप उन स्ट्रिंग्स को मिक्स नहीं करना चाहते हैं जो उन लोगों के साथ पासवर्ड हैं जो सड़क के पते, या पूर्णांक हैं जो उन लोगों के साथ एक ऑफसेट का प्रतिनिधित्व करते हैं जो निरपेक्ष मूल्य का प्रतिनिधित्व करते हैं।

परीक्षक फ्रेमवर्क एक पार्श्व-संगत रास्ते में एक typedef परिभाषित करने के लिए सक्षम बनाता है। मैं आदिम वर्गों जैसे कि intऔर अंतिम कक्षाओं जैसे के लिए भी काम करता हूं String। इसका कोई रन-टाइम ओवरहेड नहीं है और यह समानता परीक्षण नहीं तोड़ता है।

चेकर फ्रेमवर्क मैनुअल में सेक्शन टाइप एलियासेस और टाइपडेफ्स आपकी जरूरतों के आधार पर टाइप किए गए टाइप बनाने के कई तरीके बताते हैं।



-1

कुछ मामलों में, एक बाध्यकारी एनोटेशन वही हो सकता है जो आप देख रहे हैं:

https://github.com/google/guice/wiki/BindingAnnotations

या यदि आप Guice पर निर्भर नहीं होना चाहते हैं, तो बस एक नियमित एनोटेशन कर सकते हैं।


-6

आप एक Enum का उपयोग कर सकते हैं, हालांकि यह शब्दार्थ में टाइप किए गए से थोड़ा अलग है, यह केवल मूल्यों के सीमित सेट की अनुमति देता है। एक अन्य संभावित समाधान एक नामित आवरण वर्ग है, उदाहरण के लिए

public class Apple {
      public Apple(Integer i){this.i=i; }
}

लेकिन ऐसा लगता है कि रास्ता अधिक भद्दा है, विशेष रूप से यह देखते हुए कि यह कोड से स्पष्ट नहीं है कि कक्षा का अन्य उपनाम के रूप में कोई अन्य कार्य नहीं है।


-7

टाइप्डेफ आइटमों को अंतर्निहित प्रकारों को सौंपा जा सकता है जो वे नहीं हैं। कुछ लोग एक्सटेंशन के साथ इसे प्राप्त करने की कोशिश करते हैं; क्यों यह एक बुरा विचार है की व्याख्या के लिए आईबीएम पर यहाँ पढ़ें।

संपादित करें: जबकि मजबूत प्रकार का निष्कर्ष एक उपयोगी चीज है, मुझे नहीं लगता (और उम्मीद है कि हम) typedefइसे प्रबंधित भाषाओं में (कभी भी) बदसूरत सिर को पीछे करते हुए देखेंगे ।

संपादित करें 2: C # में, आप स्रोत फ़ाइल के शीर्ष पर इस तरह का उपयोग करने वाला स्टेटमेंट का उपयोग कर सकते हैं। इसका उपयोग किया जाता है ताकि आपको दिखाए गए दूसरे आइटम को न करना पड़े। नाम परिवर्तन को देखने का एकमात्र समय है जब एक गुंजाइश दो प्रकारों के बीच एक नाम टकराव का परिचय देती है। नाम बदलना एक फ़ाइल तक सीमित है, जिसके बाहर प्रत्येक चर / पैरामीटर प्रकार का उपयोग किया जाता है जिसे इसके पूर्ण नाम से जाना जाता है।

using Path = System.IO.Path;
using System.IO;

23
"टाइम्डिफ आइटमों को निहित रूप से उन प्रकारों को सौंपा जा सकता है जो वे नहीं हैं"? टाइपेडिफ बस आपको एक अन्य नाम टाइप के लिए एक उपनाम बनाने की अनुमति देता है। प्रकार अभी भी सटीक है, आपको बस इसके लिए एक छोटा नाम मिलता है। इसका टाइप इंट्रेंस से कोई लेना-देना नहीं है। -1
जलफ

@ जैलफ: वास्तव में, टाइप इंट्रेंस का उपयोग उस समाधान के रूप में किया जाता है, जिसके बारे में आप बात कर रहे हैं, लेकिन मैंने एक और उदाहरण दिया है, जहां आप एक नाम टकराने के चारों ओर पाने के लिए "टाइपडिफ" का उपयोग कर सकते हैं।
सैम हरवेल


@AlexanderMalakhov धन्यवाद, मैं आगे गया और आपके लिंक के साथ उत्तर को अद्यतन किया
डेव मैकक्लेलैंड

-14

Java में typedef की कोई आवश्यकता नहीं है। आदिम को छोड़कर सब कुछ एक वस्तु है। कोई संकेत नहीं हैं, केवल संदर्भ हैं। वे परिदृश्य जहाँ आप सामान्य रूप से टाइप-सीड्स का उपयोग करेंगे, ऐसे उदाहरण हैं जिनमें आप इसके बजाय ऑब्जेक्ट बनाते हैं।


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

28
@Bill K: meh, का कहना है कि बाद में आपको std :: map <int, std :: map <std :: string, boost :: shared_ptr <std :: string>>> :: const_iterator टाइप करना होगा। कुछ बार। उस स्थिति में, एक नाम-छोटा टाइपडिफ पठनीयता को बढ़ाता है, न कि इसमें बाधा डालता है।
जोएल

22
एक प्रकार का नाम बदलने से पठनीयता में काफी सुधार हो सकता है। क्या पढ़ना और समझना आसान है (और इस तरह अधिक पठनीय :) UnmodifiableDirectedGraph<IncrediblyFancyEdgeType, IncrediblyFancyAbstractNode.EvenFancierConcreteNode>या IncrediblyFancyGraph? मैं हमेशा यह पता लगाने के लिए परिभाषा का उल्लेख कर सकता हूं कि यह वास्तव में क्या है। इस तरह मैं यह भी सुनिश्चित कर सकता हूं कि मैं UnmodifiableDirectedGraph<IncrediblyFancyEdge,IncredilyFancyAbstractNode.SlightlyLessFancyConcreteNode>सरासर ऊब से नहीं चूकूंगा।
अलेक्जेंडर दिमित्रोव

10
@AleksandarDimitrov मुझे पता है कि आपकी टिप्पणी लगभग 3 साल पुरानी है क्योंकि मैं इसे टाइप करता हूं, लेकिन मुझे लगता है कि यह बताना बहुत ज़रूरी है कि उदाहरण कितना विपरीत और अवास्तविक है: इनमें से किसी भी वर्ग का नाम शब्द नहीं है Enterprise
केसी

4
बुरे नाम पठनीयता में बाधा डालते हैं। अच्छे नाम मदद करते हैं। अगर पूरा नाम इतना लंबा है कि टाइप्डेफ्स मदद कर सकते हैं तो यह मुश्किल है कि आपके कोड स्वरूपण को पढ़ना या शिकंजा कसना मुश्किल हो जाता है। यह तब भी मदद करता है जब किसी और के खराब रूप से चुने गए या अस्पष्ट वर्ग के नामों के साथ बातचीत करते हैं। यदि आप वास्तव में मानते हैं कि एक टाइपराइफ़ स्वाभाविक रूप से आपके कोड को अपठनीय बनाने जा रहा है, तो आपको यह भी मानना ​​चाहिए कि आपको कभी भी आयात विवरणों का उपयोग नहीं करना चाहिए और हमेशा पूरी तरह से योग्य वर्ग नामों का उल्लेख करना चाहिए।
क्रिस्टोफर नाई
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.