परिचय: वह गलती जो शायद आप अभी कर रहे हैं
\n\nएक स्थिति की कल्पना करें: आप Java में लिख रहे हैं, एनुम (enum) का उपयोग कर रहे हैं और आपको दो मानों की तुलना करनी है। आप स्वचालित रूप से if (day == Day.MONDAY) लिखते हैं। या, शायद, if (day.equals(Day.MONDAY))। और कौन सा विकल्प सही है? और क्या कोई अंतर भी है?
यह प्रश्न Stack Overflow पर सबसे लोकप्रिय प्रश्नों में से एक है। हज़ारों डेवलपर्स (शुरुआती से लेकर वरिष्ठ तक) ने यह सवाल पूछा है। यह एक छोटी सी बात लगती है। लेकिन इस 'छोटी सी बात' के पीछे JVM कैसे काम करता है, enum कैसे बनाए जाते हैं, और Java में सब कुछ इतना स्पष्ट क्यों नहीं है, इसकी गहरी समझ छिपी है।
\n\nइस लेख में हम हमेशा के लिए समझ लेंगे: Java में enum की तुलना सही तरीके से कैसे करें, कब == का उपयोग करें, और कब equals() का, और क्यों इनमें से एक विकल्प लगभग हमेशा सबसे अच्छा विकल्प होता है।
अधीर लोगों के लिए संक्षिप्त उत्तर
\n\nअगर आपको अभी उत्तर चाहिए — == का उपयोग करें।
लेकिन! इससे पहले कि आप लेख बंद करें, आइए समझते हैं कि ऐसा क्यों है, और आपको किन खतरों का सामना करना पड़ सकता है। क्योंकि शैतान, हमेशा की तरह, विवरण में है।
\n\nEnum केवल स्थिरांकों का एक सेट क्यों नहीं है?
\n\n== और equals() के बीच अंतर को समझने के लिए, हमें यह याद रखना होगा कि Java में enum वास्तव में क्या है।
प्रत्येक enum एक पूर्ण वर्ग है जो अंतर्निहित रूप से java.lang.Enum से विरासत प्राप्त करता है। प्रत्येक enum स्थिरांक इस वर्ग का एक स्थैतिक अंतिम उदाहरण है। JVM गारंटी देता है कि enum के प्रत्येक मान के लिए मेमोरी में ठीक एक ऑब्जेक्ट मौजूद है।
इस कोड को देखें:
\n\npublic enum Day {\n MONDAY,\n TUESDAY,\n WEDNESDAY,\n THURSDAY,\n FRIDAY,\n SATURDAY,\n SUNDAY\n}\n\nजब JVM इस enum को लोड करता है, तो वह ठीक 7 ऑब्जेक्ट बनाता है। Day.MONDAY हमेशा एक ही ऑब्जेक्ट होता है। हमेशा। और यह मुख्य बिंदु है।
== के माध्यम से तुलना: यह क्यों काम करता है?
\n\nJava में ऑपरेटर == ऑब्जेक्ट्स के रेफरेंस की तुलना करता है। यह सामग्री को नहीं देखता — यह जाँचता है कि क्या दो वेरिएबल मेमोरी में एक ही ऑब्जेक्ट की ओर इशारा करते हैं।
चूंकि JVM प्रत्येक enum इंस्टेंस की विशिष्टता की गारंटी देता है, इसलिए enum के लिए == तुलना पूरी तरह से काम करती है:
public class EnumComparison {\n public static void main(String[] args) {\n Day today = Day.WEDNESDAY;\n Day anotherDay = Day.WEDNESDAY;\n \n // दोनों वेरिएबल मेमोरी में एक ही ऑब्जेक्ट को संदर्भित करते हैं\n System.out.println(today == anotherDay); // true\n \n // दूसरे स्थिरांक से तुलना\n System.out.println(today == Day.MONDAY); // false\n }\n}\n\nआउटपुट:
\ntrue\nfalse\n\nसब कुछ सरल और सुरुचिपूर्ण है। लेकिन आइए देखें कि हुड के नीचे क्या होता है।
\n\nयह सुरक्षित क्यों है? JVM की गारंटी
\n\nJava भाषा विनिर्देश (JLS 8.9) गारंटी देता है कि प्रत्येक enum मान क्लास लोड होने पर ठीक एक बार प्रारंभ किया जाता है। कोई भी रिफ्लेक्शन, सीरियलाइज़ेशन या क्लोनिंग आपको डुप्लिकेट बनाने की अनुमति नहीं देगा। भले ही आप new का उपयोग करने का प्रयास करें — कंपाइलर एक त्रुटि देगा।
इसलिए, enum के लिए == केवल 'काम करता है' नहीं है, यह तुलना का सबसे तेज़ और सबसे विश्वसनीय तरीका है।
equals() के माध्यम से तुलना: काम करता है, लेकिन बारीकियाँ हैं
\n\nequals() विधि भी काम करती है। Enum वर्ग equals() को ओवरराइड करता है, और अंदर से यह == का उपयोग करता है:
// java.lang.Enum से वास्तविक कोड\npublic final boolean equals(Object other) {\n return this == other;\n}\n\nअर्थात, day.equals(Day.MONDAY) को कॉल करना अंततः वही करता है जो day == Day.MONDAY करता है। लेकिन एक महत्वपूर्ण अंतर है:
null के साथ समस्या
\n\nयदि आपका वेरिएबल हो सकता है