दिलचस्प पोस्ट
आईओएस अद्वितीय उपयोगकर्ता पहचानकर्ता एक्लेप्से में जर्सी मेवेन क्विकस्टार्ट मूलरूप शैली UIWebView में प्रमाणीकरण चुनौती कैसे प्रदर्शित करें? दृश्य सी ++ का उपयोग करके कोड के पीछे असेंबली को कैसे देखें? IPhone सिम्युलेटर में स्थान सेट करें आईडी मिलान के आधार पर एक तालिका से दूसरे तालिका में SQL अद्यतन घातक त्रुटि: अधिकतम 30 सेकंड का निष्पादन समय पार हो गया Excel में सूत्र से खाली सेल लौटें कैसे LINQ में% की तरह एसक्यूएल करते हैं? कैसे एक पासवर्ड हैश करने के लिए पायथन में स्विच स्टेटमेंट के लिए प्रतिस्थापन? JQuery का उपयोग करते हुए मैं एक टेक्स्टबॉक्स का मान कैसे प्राप्त करूं? एंड्रॉइड में हवाई जहाज मोड टॉगल करें Srand को शुरू करने का अनुशंसित तरीका है? गतिविधियों के बीच वस्तुओं की सरणी सूची

जावा में बेनामी (आंतरिक) वर्ग कैसे उपयोग किए जाते हैं?

जावा में गुमनाम कक्षाओं का क्या उपयोग है? क्या हम कह सकते हैं कि अनाम वर्ग का उपयोग जावा के लाभों में से एक है?

वेब के समाधान से एकत्रित समाधान "जावा में बेनामी (आंतरिक) वर्ग कैसे उपयोग किए जाते हैं?"

एक "गुमनाम वर्ग" द्वारा, मैं इसे लेता हूं आप का मतलब गुमनाम इनर क्लास

किसी अज्ञात अंतराल में किसी वस्तु का एक उदाहरण बनाते समय उपयोगी हो सकता है, जैसे कि "अतिरिक्त" जैसे ओलोड करने के तरीके, वास्तव में एक वर्ग को उप-वर्ग के बिना

मैं इसे ईवेंट श्रोता को संलग्न करने के लिए एक शॉर्टकट के रूप में उपयोग करते हैं:

button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // do something } }); 

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

मैं केवल इस तकनीक का इस्तेमाल "त्वरित और गंदे" कार्यों के लिए करता हूं जहां पूरे वर्ग को अनावश्यक लगता है। बहुत से गुमनाम आंतरिक कक्षाएं कर रही हैं जो वास्तव में एक ही चीज़ को एक वास्तविक वर्ग में पुनर्संचित किया जाना चाहिए, यह एक आंतरिक वर्ग या एक अलग वर्ग होना चाहिए।

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

 public interface F<A, B> { B f(A a); } 

आप जावा में प्रथम श्रेणी के फ़ंक्शन को बनाने के लिए इस गुमनाम रूप से उपयोग कर सकते हैं। मान लीजिए कि आपके पास निम्नलिखित विधि है जो दी गई सूची में मैं से पहले बड़ी संख्या देता है, या यदि कोई संख्या बड़ा नहीं है I:

 public static int larger(final List<Integer> ns, final int i) { for (Integer n : ns) if (n > i) return n; return i; } 

और फिर आपके पास एक और तरीका है जो दी गई सूची में से छोटी से पहले नंबर पर देता है, या यदि कोई संख्या छोटा नहीं है I:

 public static int smaller(final List<Integer> ns, final int i) { for (Integer n : ns) if (n < i) return n; return i; } 

ये विधियां लगभग समान हैं। प्रथम श्रेणी के फ़ंक्शन प्रकार एफ का उपयोग करके, हम इन्हें एक विधि के रूप में निम्न प्रकार से लिख सकते हैं:

 public static <T> T firstMatch(final List<T> ts, final F<T, Boolean> f, T z) { for (T t : ts) if (ff(t)) return t; return z; } 

आप पहली मैच विधि का उपयोग करने के लिए एक अज्ञात वर्ग का उपयोग कर सकते हैं:

 F<Integer, Boolean> greaterThanTen = new F<Integer, Boolean> { Boolean f(final Integer n) { return n > 10; } }; int moreThanMyFingersCanCount = firstMatch(xs, greaterThanTen, x); 

यह एक वास्तविक उदाहरण है, लेकिन यह देखने में आसान है कि वे कार्य को पार करने में सक्षम हैं जैसे कि वे मूल्य थे एक बहुत उपयोगी विशेषता है जोएल खुद द्वारा "आपका प्रोग्रामिंग भाषा ऐसा कर सकते हैं" देखें

इस शैली में जावा प्रोग्रामिंग के लिए एक अच्छी लाइब्रेरी: कार्यात्मक जावा

मैं उन्हें कभी-कभी नक्शा तात्कालिकता के लिए सिंटैक्स हैक के रूप में उपयोग करता हूं:

 Map map = new HashMap() {{ put("key", "value"); }}; 

बनाम

 Map map = new HashMap(); map.put("key", "value"); 

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

बेनामी इनर क्लास का उपयोग निम्नलिखित परिदृश्य में किया जाता है:

1.) ओवरराइडिंग (उप वर्गीकरण) के लिए, जब क्लास की परिभाषा मौजूदा केस को छोड़कर प्रयोग करने योग्य नहीं है:

 class A{ public void methodA() { System.out.println("methodA"); } } class B{ A a = new A() { public void methodA() { System.out.println("anonymous methodA"); } }; } 

2.) एक इंटरफ़ेस को लागू करने के लिए, जब इंटरफ़ेस का कार्यान्वयन केवल मौजूदा मामले के लिए आवश्यक होता है:

 interface interfaceA{ public void methodA(); } class B{ interfaceA a = new interfaceA() { public void methodA() { System.out.println("anonymous methodA implementer"); } }; } 

3.) तर्क परिभाषित बेनामी आंतरिक वर्ग:

  interface Foo { void methodFoo(); } class B{ void do(Foo f) { } } class A{ void methodA() { B b = new B(); b.do(new Foo() { public void methodFoo() { System.out.println("methodFoo"); } }); } } 

वे आम तौर पर कॉलबैक के एक क्रियाशील रूप के रूप में उपयोग किए जाते हैं।

मुझे लगता है कि आप कह सकते हैं कि उन्हें न होने के मुकाबले यह एक फायदा है, और हर बार एक नामित वर्ग बनाना पड़ता है, लेकिन अन्य भाषाओं में समान अवधारणाओं को बेहतर ढंग से कार्यान्वित किया जाता है (क्लोजर या ब्लॉकों के रूप में)

यहाँ एक स्विंग उदाहरण है

 myButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // do stuff here... } }); 

यद्यपि यह अभी भी मैसेरियल वर्बोस है, यह आपको बहुत ज्यादा बेहतर है क्योंकि आप इसे नामित कक्षा के हर एक के लिए नामित वर्ग को परिभाषित करने के लिए मजबूर करते हैं (हालाँकि स्थिति और पुन: उपयोग के आधार पर, हालांकि अभी भी बेहतर दृष्टिकोण हो सकता है)

आप उन परिस्थितियों में इसका उपयोग करते हैं जहां आपको किसी दूसरे उद्देश्य के लिए एक विशेष उद्देश्य के लिए एक वर्ग बनाने की आवश्यकता होती है, उदाहरण के लिए, एक श्रोता के रूप में, एक रननेबल (थ्रेड अंडे) आदि।

विचार यह है कि आप उन्हें किसी फ़ंक्शन के कोड के अंदर से कॉल करते हैं ताकि आप उन्हें कहीं और न देखें, इसलिए उन्हें नाम देने की आवश्यकता नहीं है। संकलक सिर्फ उन्हें बताता है।

वे अनिवार्य रूप से वाक्यात्मक चीनी हैं, और आम तौर पर कहीं और स्थानांतरित हो जाते हैं क्योंकि वे बड़े होते हैं

मुझे यकीन नहीं है कि यह जावा के फायदों में से एक है, यद्यपि यदि आप उनका उपयोग करते हैं (और हम सभी को दुर्भाग्य से उपयोग करते हैं), तो आप यह तर्क दे सकते हैं कि वे एक हैं।

अनामिका के लिए गाइडलाइन

  1. अनाम वर्ग को एक साथ घोषित और आरम्भ किया जाता है।

  2. अनाम वर्ग को एक या केवल एक वर्ग या इंटरफ़ेस resp को बढ़ाया या लागू करना चाहिए।

  3. उपनाम वर्ग के नाम के रूप में कोई नाम नहीं है, इसका उपयोग केवल एक बार किया जा सकता है।

उदाहरण के लिए:

 button.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub } }); 
 new Thread() { public void run() { try { Thread.sleep(300); } catch (InterruptedException e) { System.out.println("Exception message: " + e.getMessage()); System.out.println("Exception cause: " + e.getCause()); } } }.start(); 

यह धागा का उपयोग करके गुमनाम इनर प्रकार के उदाहरण में से एक है

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

एक अनाम आंतरिक वर्ग के साथ आप आसपास के वर्ग के अंतिम और सदस्य चर तक पहुंच सकते हैं, और यह सुनने वालों में आसान है।

लेकिन एक बड़ा फायदा यह है कि आंतरिक कक्षा कोड, जो (कम से कम होना चाहिए) कसकर आसपास के वर्ग / विधि / ब्लॉक के साथ युग्मित किया गया है, का विशिष्ट संदर्भ (आसपास के वर्ग, विधि और ब्लॉक) है।

मैं नई थ्रेड्स कॉल करने के लिए अनाम वस्तुओं का उपयोग करता हूं ..

 new Thread(new Runnable() { public void run() { // you code } }).start(); 

विभिन्न ऑब्जेक्ट के लिए अलग-अलग कार्यान्वयन करते समय बेनामी इनर क्लास फायदेमंद हो सकता है। लेकिन बहुत कम इस्तेमाल किया जाना चाहिए क्योंकि यह प्रोग्राम पठनीयता के लिए समस्या पैदा करता है।

एक आंतरिक वर्ग बाहरी कक्षा के एक उदाहरण से जुड़ा हुआ है और दो विशेष प्रकार हैं: लोकल क्लास और बेनामी क्लास । एक गुमनाम वर्ग हमें एक ही समय में एक कक्षा को घोषित करने और इन्स्तांत करने में सक्षम बनाता है, इसलिए कोड संक्षिप्त बना देता है। हम उन का उपयोग करते हैं जब हमें केवल एक बार स्थानीय वर्ग की आवश्यकता होती है क्योंकि उनका नाम नहीं है

डॉक्टर के उदाहरण पर विचार करें जहां हमारे पास एक Person वर्ग है:

 public class Person { public enum Sex { MALE, FEMALE } String name; LocalDate birthday; Sex gender; String emailAddress; public int getAge() { // ... } public void printPerson() { // ... } } 

और हमारे पास ऐसे सदस्यों को मुद्रित करने की एक विधि है जो खोज मापदंड से मेल खाते हैं:

 public static void printPersons( List<Person> roster, CheckPerson tester) { for (Person p : roster) { if (tester.test(p)) { p.printPerson(); } } } 

जहां CheckPerson एक इंटरफ़ेस है:

 interface CheckPerson { boolean test(Person p); } 

अब हम अज्ञात वर्ग का उपयोग कर सकते हैं जो इस मापदंड को निर्दिष्ट करने के लिए इस इंटरफ़ेस को लागू करता है:

 printPersons( roster, new CheckPerson() { public boolean test(Person p) { return p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25; } } ); 

यहां इंटरफ़ेस बहुत सरल है और गुमनाम वर्ग का सिंटैक्स बोझल और अस्पष्ट लगता है।

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

 printPersons( roster, (Person p) -> p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25 ); 

हम इंटरफ़ेस CheckPerson स्थान पर एक मानक कार्यात्मक इंटरफ़ेस का उपयोग कर सकते हैं, जो आगे आवश्यक कोड की मात्रा को कम करेगा।

कक्षा अंतिम रूप में अज्ञात कक्षाओं में से एक का मुख्य उपयोग जो अंतिम रूप धारक को कहते हैं जब तक आप वास्तव में उनकी ज़रूरत नहीं कर लेते, अंतिम रूप से तरीकों से जावा दुनिया में इसे बचा जाना चाहिए। आपको याद रखना चाहिए, जब आप उप-वर्गों के लिए अंतिम रूप से विधि को ओवरराइड करते हैं, तो आपको हमेशा super.finalize() को भी आमंत्रित करना चाहिए, क्योंकि सुपर क्लास की अंतिम रूप वाली विधि स्वचालित रूप से शुरू नहीं होगी और आपको स्मृति लीक के साथ परेशानी हो सकती है।

इसलिए ऊपर उल्लेखित तथ्य पर विचार करते हुए, आप केवल गुमनाम कक्षाओं का उपयोग कर सकते हैं जैसे:

 public class HeavyClass{ private final Object finalizerGuardian = new Object() { @Override protected void finalize() throws Throwable{ //Finalize outer HeavyClass object } }; } 

इस तकनीक का उपयोग करके आप HeavyClass और आपके अन्य डेवलपर्स को HeavyClass क्लास के प्रत्येक उप-कक्षा में super.finalize() कॉल करने के लिए HeavyClass देते हैं जो विधि को अंतिम रूप देने की आवश्यकता होती है।

आप इस तरह अनाम क्लास का इस्तेमाल कर सकते हैं

 TreeSet treeSetObj = new TreeSet(new Comparator() { public int compare(String i1,String i2) { return i2.compareTo(i1); } }); 

यहां कोई भी नहीं बताया गया है, लेकिन आप जेनेरिक प्रकार तर्क रखने के लिए अनाम वर्ग का उपयोग भी कर सकते हैं (जो आमतौर पर प्रकार के विलोपन के कारण खो गया) :

 public abstract class TypeHolder<T> { private final Type type; public TypeReference() { // you may do do additional sanity checks here final Type superClass = getClass().getGenericSuperclass(); this.type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; } public final Type getType() { return this.type; } } 

यदि आप इस वर्ग को अनाम तरीके से इन्स्तांत करेंगे

 TypeHolder<List<String>, Map<Ineger, Long>> holder = new TypeHolder<List<String>, Map<Ineger, Long>>() {}; 

तो ऐसे holder उदाहरण में पारित प्रकार की गैर-मिटाने वाली परिभाषा शामिल होगी।

प्रयोग

यह मान्यकर्ता / deserializators के निर्माण के लिए बहुत आसान है इसके अलावा आप सामान्य प्रकार को प्रतिबिंब के साथ इन्स्तांत कर सकते हैं (इसलिए यदि आप कभी भी new T() parametrized प्रकार में करना चाहते थे – आपका स्वागत है!)

कमियां / सीमाएं

  1. आपको सामान्य पैरामीटर स्पष्ट रूप से देना चाहिए। ऐसा करने में विफल रहने पर पैरामीटर हानि टाइप की जाएगी
  2. प्रत्येक इंस्टीलेशन के लिए संकलक द्वारा उत्पन्न होने वाले अतिरिक्त क्लास का खर्च आएगा जो कि प्रदूषण / जार ब्लोटिंग के लिए क्लासपाथ की ओर जाता है

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

 import java.util.Scanner; abstract class AnonymousInner { abstract void sum(); } class AnonymousInnerMain { public static void main(String []k){ Scanner sn = new Scanner(System.in); System.out.println("Enter two vlaues"); int a= Integer.parseInt(sn.nextLine()); int b= Integer.parseInt(sn.nextLine()); AnonymousInner ac = new AnonymousInner(){ void sum(){ int c= a+b; System.out.println("Sum of two number is: "+c); } }; ac.sum(); } }