मैं Java इंटरफ़ेस में एक स्थिर विधि को परिभाषित क्यों नहीं कर सकता?




interface static-methods (16)

मैं Java इंटरफ़ेस में एक स्थिर विधि को परिभाषित क्यों नहीं कर सकता?

दरअसल आप जावा 8 में कर सकते हैं।

जावा docs.oracle/staticMethod अनुसार:

एक स्थैतिक विधि एक विधि है जो उस वर्ग से जुड़ी होती है जिसमें इसे किसी वस्तु के बजाय परिभाषित किया जाता है। कक्षा का हर उदाहरण अपनी स्थिर विधियों को साझा करता है

जावा 8 में एक इंटरफ़ेस में डिफ़ॉल्ट विधियां और स्थैतिक विधियां हो सकती हैं । यह हमारे पुस्तकालयों में सहायक तरीकों को व्यवस्थित करना हमारे लिए आसान बनाता है। हम एक अलग वर्ग के बजाय एक ही इंटरफ़ेस में इंटरफ़ेस के लिए विशिष्ट स्थिर विधियां रख सकते हैं।

डिफ़ॉल्ट विधि का उदाहरण:

list.sort(ordering);

के बजाय

Collections.sort(list, ordering);

स्थैतिक विधि का उदाहरण ( docs.oracle/staticMethod स्वयं):

public interface TimeClient {
    // ...
    static public ZoneId getZoneId (String zoneString) {
        try {
            return ZoneId.of(zoneString);
        } catch (DateTimeException e) {
            System.err.println("Invalid time zone: " + zoneString +
                "; using default time zone instead.");
            return ZoneId.systemDefault();
        }
    }

    default public ZonedDateTime getZonedDateTime(String zoneString) {
        return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }    
}

उदाहरण यहां दिया गया है:

public interface IXMLizable<T>
{
  static T newInstanceFromXML(Element e);
  Element toXMLElement();
}

बेशक यह काम नहीं करेगा। पर क्यों नहीं?

संभावित मुद्दों में से एक होगा, जब आप कॉल करते हैं तो क्या होता है:

IXMLizable.newInstanceFromXML(e);

इस मामले में, मुझे लगता है कि इसे सिर्फ एक खाली विधि (यानी {}) पर कॉल करना चाहिए। सभी उप-वर्गों को स्थैतिक विधि को लागू करने के लिए मजबूर किया जाएगा, इसलिए स्थैतिक विधि को कॉल करते समय वे सभी ठीक होंगे। तो यह क्यों संभव नहीं है?

संपादित करें: मुझे लगता है कि मैं ऐसे उत्तर की तलाश में हूं जो गहरा है "क्योंकि जावा जिस तरह से है"।

क्या कोई विशेष तकनीकी कारण है कि स्थैतिक तरीकों को अधिलेखित नहीं किया जा सकता है? यही कारण है कि जावा के डिजाइनरों ने उदाहरण विधियों को ओवरराइड करने का फैसला क्यों किया लेकिन स्थिर तरीकों से नहीं?

संपादित करें: मेरे डिजाइन के साथ समस्या यह है कि मैं कोडिंग सम्मेलन को लागू करने के लिए इंटरफेस का उपयोग करने की कोशिश कर रहा हूं।

यही है, इंटरफेस का लक्ष्य दो गुना है:

  1. मैं IXMLizable इंटरफ़ेस चाहता हूं कि मुझे कक्षाओं को परिवर्तित करने की अनुमति दें जो इसे XML तत्वों (पॉलिमॉर्फिज्म का उपयोग करके, ठीक काम करता है) में लागू करें।

  2. यदि कोई ऐसा वर्ग का नया उदाहरण बनाना चाहता है जो IXMLizable इंटरफ़ेस लागू करता है, तो वे हमेशा यह जान लेंगे कि एक नयाInstanceFromXML (एलिमेंट ई) स्थिर कन्स्ट्रक्टर होगा।

इंटरफेस में सिर्फ एक टिप्पणी डालने के अलावा, यह सुनिश्चित करने का कोई और तरीका है?

संपादित करें: जावा 8 के रूप में, इंटरफेस में स्थिर विधियों की अनुमति है।


जावा 8 स्थिर इंटरफ़ेस विधियों की अनुमति देता है

जावा 8 के साथ, इंटरफेस में स्थिर तरीके हो सकते हैं। उनके पास ठोस उदाहरण विधियां भी हो सकती हैं, लेकिन उदाहरण फ़ील्ड नहीं।

यहां वास्तव में दो प्रश्न हैं:

  1. क्यों, बुरे पुराने दिनों में, इंटरफेस में स्थैतिक तरीकों को शामिल नहीं किया जा सका?
  2. स्थैतिक विधियों को ओवरराइड क्यों नहीं किया जा सकता है?

इंटरफेस में स्टेटिक तरीकों

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

अंत में, जावा 8 ने स्थिर इंटरफेस विधियों के साथ-साथ ओवरराइड-सक्षम इंस्टेंस विधियों को डिफ़ॉल्ट कार्यान्वयन के साथ पेश किया। हालांकि वे अभी भी उदाहरण फ़ील्ड नहीं हो सकते हैं। ये विशेषताएं लैम्ब्डा अभिव्यक्ति समर्थन का हिस्सा हैं, और आप जेएसआर 335 के भाग एच में उनके बारे में अधिक पढ़ सकते हैं

स्थिर तरीकों को ओवरराइड करना

दूसरे प्रश्न का उत्तर थोड़ा और जटिल है।

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

उदाहरण के तरीकों के काम पर एक छोटी सी पृष्ठभूमि यह समझने के लिए जरूरी है कि यहां क्या हो रहा है। मुझे यकीन है कि वास्तविक कार्यान्वयन काफी अलग है, लेकिन मुझे विधि प्रेषण की मेरी धारणा को समझाएं, जो मॉडल ने व्यवहार को सटीक रूप से देखा।

दिखाएं कि प्रत्येक वर्ग में हैश तालिका है जो विधि को लागू करने के लिए कोड के वास्तविक हिस्से में विधि हस्ताक्षर (नाम और पैरामीटर प्रकार) को मैप करती है। जब वर्चुअल मशीन किसी उदाहरण पर किसी विधि को लागू करने का प्रयास करती है, तो यह ऑब्जेक्ट को अपनी कक्षा के लिए पूछताछ करती है और कक्षा की तालिका में अनुरोधित हस्ताक्षर को देखती है। यदि कोई विधि निकाय पाया जाता है, तो इसे बुलाया जाता है। अन्यथा, कक्षा के मूल वर्ग को प्राप्त किया जाता है, और लुकअप दोहराया जाता है। यह तब तक प्राप्त होता है जब तक कि विधि नहीं मिलती है, या कोई और माता-पिता वर्ग नहीं होते हैं- जिसके परिणामस्वरूप NoSuchMethodError

यदि एक सुपरक्लास और उप-वर्ग दोनों में एक ही विधि हस्ताक्षर के लिए दोनों तालिकाओं में प्रवेश होता है, तो उप वर्ग का संस्करण पहले सामना किया जाता है, और सुपरक्लास के संस्करण का कभी भी उपयोग नहीं किया जाता है-यह एक "ओवरराइड" है।

अब, मान लीजिए कि हम ऑब्जेक्ट इंस्टेंस को छोड़ दें और बस सबक्लास के साथ शुरू करें। संकल्प उपरोक्त के रूप में आगे बढ़ सकता है, जिससे आपको "अतिरंजित" स्थैतिक विधि मिलती है। संकल्प संकलन-समय पर हो सकता है, हालांकि, चूंकि संकलक किसी वर्ग के लिए अनिर्दिष्ट प्रकार के किसी ऑब्जेक्ट से पूछताछ करने के लिए रनटाइम तक प्रतीक्षा करने के बजाए किसी ज्ञात वर्ग से शुरू होता है। एक स्थैतिक विधि "ओवरराइडिंग" में कोई बिंदु नहीं है क्योंकि कोई भी वांछित संस्करण वाले वर्ग को हमेशा निर्दिष्ट कर सकता है।

कन्स्ट्रक्टर "इंटरफेस"

प्रश्न के हालिया संपादन को संबोधित करने के लिए यहां कुछ और सामग्री दी गई है।

ऐसा लगता है कि आप IXMLizable प्रत्येक कार्यान्वयन के लिए प्रभावी रूप से एक कन्स्ट्रक्टर-जैसी विधि को IXMLizable । एक मिनट के लिए इंटरफेस के साथ इसे लागू करने की कोशिश करने के बारे में भूल जाओ, और दिखाएं कि आपके पास कुछ आवश्यकताएं हैं जो इस आवश्यकता को पूरा करती हैं। आप इसका इस्तेमाल कैसे करेंगे?

class Foo implements IXMLizable<Foo> {
  public static Foo newInstanceFromXML(Element e) { ... }
}

Foo obj = Foo.newInstanceFromXML(e);

चूंकि आपको नई वस्तु को "निर्माण" करते समय कंक्रीट प्रकार Foo को स्पष्ट रूप से नामित करना होगा, इसलिए संकलक यह सत्यापित कर सकता है कि इसमें वास्तव में आवश्यक फैक्ट्री विधि है। और अगर ऐसा नहीं होता है, तो क्या? यदि मैं एक IXMLizable को कार्यान्वित कर सकता हूं जिसमें "कन्स्ट्रक्टर" की कमी है, और मैं एक उदाहरण बना देता हूं और इसे अपने कोड में पास करता हूं, तो यह सभी आवश्यक इंटरफेस के साथ एक IXMLizable है।

निर्माण कार्यान्वयन का हिस्सा है, इंटरफ़ेस नहीं। इंटरफ़ेस के साथ सफलतापूर्वक काम करने वाला कोई भी कोड कन्स्ट्रक्टर की परवाह नहीं करता है। कन्स्ट्रक्टर के बारे में परवाह करने वाले किसी भी कोड को कंक्रीट प्रकार को वैसे भी जानने की जरूरत है, और इंटरफ़ेस को अनदेखा किया जा सकता है।


आप एक इंटरफ़ेस में स्थिर विधियों को परिभाषित नहीं कर सकते हैं क्योंकि स्थैतिक विधियां कक्षा के उदाहरण के लिए कक्षा से संबंधित नहीं हैं, और इंटरफेस कक्षाएं नहीं हैं। यहां और पढ़ें।

हालांकि, अगर आप चाहते हैं कि आप यह कर सकते हैं:

public class A {
  public static void methodX() {
  }
}

public class B extends A {
  public static void methodX() {
  }
}

इस मामले में आपके पास दो वर्ग हैं जिनमें 2 अलग-अलग स्थैतिक विधियां हैं जिन्हें methodX () कहा जाता है।


आम तौर पर यह फैक्टरी पैटर्न का उपयोग करके किया जाता है

public interface IXMLizableFactory<T extends IXMLizable> {
  public T newInstanceFromXML(Element e);
}

public interface IXMLizable {
  public Element toXMLElement();
}

इंटरफेस पॉलिमॉर्फिज्म से चिंतित हैं जो मूल रूप से ऑब्जेक्ट इंस्टेंस से बंधे हैं, कक्षाओं में नहीं। इसलिए स्थैतिक एक इंटरफ़ेस के संदर्भ में समझ में नहीं आता है।


इसे हल करने के लिए: त्रुटि: गायब विधि निकाय, या अमूर्त स्थैतिक शून्य मुख्य (स्ट्रिंग [] तर्क) घोषित करें;

interface I
{
    int x=20;
    void getValue();
    static void main(String[] args){};//Put curly braces 
}
class InterDemo implements I
{
    public void getValue()
    {
    System.out.println(x);
    }
    public static void main(String[] args)
    {
    InterDemo i=new InterDemo();
    i.getValue();   
    }

}

आउटपुट: 20

अब हम इंटरफ़ेस में स्थिर विधि का उपयोग कर सकते हैं


कई उत्तरों ने अतिसंवेदनशील स्थैतिक तरीकों की अवधारणा के साथ समस्याओं पर चर्चा की है। हालांकि कभी-कभी आप एक ऐसे पैटर्न में आते हैं जहां ऐसा लगता है कि आप इसका उपयोग करना चाहते हैं।

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

cmd = createCmd(Person.getCreateCmdId());
Person p = cmd.execute();

और आईडी द्वारा एक व्यक्ति को लोड करने के लिए आप करेंगे

cmd = createCmd(Person.getGetCmdId());
cmd.set(ID, id);
Person p = cmd.execute();

यह काफी सुविधाजनक है, हालांकि इसकी समस्याएं हैं; विशेष रूप से स्थिर तरीकों का अस्तित्व इंटरफ़ेस में लागू नहीं किया जा सकता है। इंटरफ़ेस में एक अतिव्यापी स्थैतिक विधि वही होगी जो हमें चाहिए, अगर यह किसी भी तरह से काम कर सकती है।

ईजेबी होम इंटरफेस करके इस समस्या को हल करते हैं; प्रत्येक वस्तु जानता है कि अपने घर को कैसे ढूंढें और घर में "स्थैतिक" विधियां हैं। इस तरह "स्थैतिक" विधियों को आवश्यकतानुसार ओवरराइड किया जा सकता है, और आप सामान्य रूप से अव्यवस्थित नहीं होते हैं (इसे "रिमोट" कहा जाता है) इंटरफ़ेस जो आपके बीन के उदाहरण पर लागू नहीं होता है। बस सामान्य इंटरफ़ेस को "getHome ()" विधि निर्दिष्ट करें। होम ऑब्जेक्ट का एक उदाहरण लौटाएं (जो एक सिंगलटन हो सकता है, मुझे लगता है) और कॉलर सभी व्यक्ति वस्तुओं को प्रभावित करने वाले संचालन कर सकता है।


कुछ लागू किया जा सकता है स्थिर इंटरफ़ेस (एक इंटरफ़ेस में स्थिर विधि के बजाय)। किसी दिए गए स्थिर इंटरफेस को लागू करने वाले सभी वर्गों को संबंधित स्थिर तरीकों को लागू करना चाहिए। आप किसी भी वर्ग क्लैज का उपयोग कर स्थिर इंटरफ़ेस एसआई प्राप्त कर सकते हैं

SI si = clazz.getStatic(SI.class); // null if clazz doesn't implement SI
// alternatively if the class is known at compile time
SI si = Someclass.static.SI; // either compiler errror or not null

तो आप si.method(params) को कॉल कर सकते हैं। यह उपयोगी होगा (उदाहरण के लिए फैक्टरी डिजाइन पैटर्न के लिए) क्योंकि आप एक संकलित समय अज्ञात वर्ग से एसआई स्थैतिक विधियों के कार्यान्वयन (या कार्यान्वयन की जांच) प्राप्त कर सकते हैं! एक गतिशील प्रेषण आवश्यक है और आप इसे विस्तारित करके कक्षा के स्थिर तरीकों (यदि अंतिम नहीं हैं) को ओवरराइड कर सकते हैं (जब स्थिर इंटरफ़ेस के माध्यम से बुलाया जाता है)। जाहिर है, ये विधियां केवल अपनी कक्षा के स्थैतिक चर तक पहुंच सकती हैं।


खैर, जेनेरिक के बिना, स्थैतिक इंटरफेस बेकार हैं क्योंकि सभी स्थिर विधि कॉल संकलित समय पर हल किए जाते हैं। तो, उनके लिए कोई वास्तविक उपयोग नहीं है।

जेनेरिक के साथ, उन्होंने डिफ़ॉल्ट कार्यान्वयन के साथ या बिना उपयोग किया है। जाहिर है, ओवरराइडिंग की आवश्यकता होगी और इसी तरह। हालांकि, मेरा अनुमान है कि इस तरह का उपयोग बहुत ओओ नहीं था (जैसा कि अन्य उत्तरों गड़बड़ी से बाहर निकलते हैं) और इसलिए उन्हें लागू करने के लिए आवश्यक प्रयासों के लायक नहीं माना गया था।


जबकि मुझे एहसास हुआ कि जावा 8 इस मुद्दे को हल करता है, मैंने सोचा कि मैं उस परिदृश्य के साथ झुकाऊंगा जिसमें मैं वर्तमान में काम कर रहा हूं (जावा 7 का उपयोग करने में बंद) जहां इंटरफ़ेस में स्थिर विधियां निर्दिष्ट करने में सक्षम होना उपयोगी होगा।

मेरे पास कई enum परिभाषाएं हैं जहां मैंने कई कारणों से मूल्यों का मूल्यांकन करने वाले सहायक तरीकों के साथ "आईडी" और "प्रदर्शन नाम" फ़ील्ड को परिभाषित किया है। एक इंटरफ़ेस को कार्यान्वित करने से मुझे यह सुनिश्चित करने की अनुमति मिलती है कि गेटर विधियां जगह पर हैं लेकिन स्थैतिक सहायक तरीके नहीं हैं। एक enum होने के नाते, वास्तव में विरासत अमूर्त वर्ग में कुछ सहायक तरीकों को ऑफ़लोड करने के लिए एक साफ तरीका नहीं है या इस तरह के कुछ तरीकों को enum में परिभाषित किया जाना चाहिए। इसके अलावा, क्योंकि यह एक enum है, आप कभी भी इसे एक उन्नत वस्तु के रूप में पारित करने में सक्षम नहीं होंगे और इसे इंटरफ़ेस प्रकार के रूप में मानेंगे, लेकिन एक इंटरफ़ेस के माध्यम से स्थिर सहायक विधियों के अस्तित्व की आवश्यकता होने में सक्षम होने के बारे में मुझे क्या पसंद है यह जावा 8 में समर्थित है।

यहां मेरे बिंदु को चित्रित करने वाला कोड है।

इंटरफ़ेस परिभाषा:

public interface IGenericEnum <T extends Enum<T>> {
    String getId();
    String getDisplayName();
    //If I was using Java 8 static helper methods would go here
}

एक enum परिभाषा का उदाहरण:

public enum ExecutionModeType implements IGenericEnum<ExecutionModeType> {
    STANDARD ("Standard", "Standard Mode"),
    DEBUG ("Debug", "Debug Mode");

    String id;
    String displayName;

    //Getter methods
    public String getId() {
        return id;
    }

    public String getDisplayName() {
        return displayName;
    }

    //Constructor
    private ExecutionModeType(String id, String displayName) {
        this.id = id;
        this.displayName = displayName;
    }

    //Helper methods - not enforced by Interface
    public static boolean isValidId(String id) {
        return GenericEnumUtility.isValidId(ExecutionModeType.class, id);
    }

    public static String printIdOptions(String delimiter){
        return GenericEnumUtility.printIdOptions(ExecutionModeType.class, delimiter);
    }

    public static String[] getIdArray(){
        return GenericEnumUtility.getIdArray(ExecutionModeType.class);
    }

    public static ExecutionModeType getById(String id) throws NoSuchObjectException {
        return GenericEnumUtility.getById(ExecutionModeType.class, id);
    }
}

जेनेरिक enum उपयोगिता परिभाषा:

public class GenericEnumUtility {
    public static <T extends Enum<T> & IGenericEnum<T>> boolean isValidId(Class<T> enumType, String id) {       
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(enumOption.getId().equals(id)) {
                return true;
            }
        }

        return false;
    }

    public static <T extends Enum<T> & IGenericEnum<T>> String printIdOptions(Class<T> enumType, String delimiter){
        String ret = "";
        delimiter = delimiter == null ? " " : delimiter;

        int i = 0;
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(i == 0) {
                ret = enumOption.getId();
            } else {
                ret += delimiter + enumOption.getId();
            }           
            i++;
        }

        return ret;
    }

    public static <T extends Enum<T> & IGenericEnum<T>> String[] getIdArray(Class<T> enumType){
        List<String> idValues = new ArrayList<String>();

        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            idValues.add(enumOption.getId());
        }

        return idValues.toArray(new String[idValues.size()]);
    }

    @SuppressWarnings("unchecked")
    public static <T extends Enum<T> & IGenericEnum<T>> T getById(Class<T> enumType, String id) throws NoSuchObjectException {
        id = id == null ? "" : id;
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(id.equals(enumOption.getId())) {
                return (T)enumOption;
            }
        }

        throw new NoSuchObjectException(String.format("ERROR: \"%s\" is not a valid ID. Valid IDs are: %s.", id, printIdOptions(enumType, " , ")));
    }
}

मुझे लगता है कि जावा में स्थिर इंटरफ़ेस विधियां नहीं हैं क्योंकि आपको उनकी आवश्यकता नहीं है। आप सोच सकते हैं कि आप करते हैं, लेकिन ... आप उनका उपयोग कैसे करेंगे? यदि आप उन्हें कॉल करना चाहते हैं

MyImplClass.myMethod()

तो आपको इंटरफ़ेस में इसे घोषित करने की आवश्यकता नहीं है। यदि आप उन्हें कॉल करना चाहते हैं

myInstance.myMethod()

तो यह स्थैतिक नहीं होना चाहिए। If you are actually going to use first way, but just want to enforce each implementation to have such static method, then it is really a coding convention, not a contract between instance that implements an interface and calling code.

Interfaces allow you to define contract between instance of class that implement the interface and calling code. And java helps you to be sure that this contract is not violated, so you can rely on it and don't worry what class implements this contract, just "someone who signed a contract" is enough. In case of static interfaces your code

MyImplClass.myMethod()

does not rely on the fact that each interface implementation has this method, so you do not need java to help you to be sure with it.


यह पहले से ही पूछा और उत्तर here

मेरे उत्तर को डुप्लिकेट करने के लिए:

इंटरफ़ेस में स्थिर विधि घोषित करने का कोई बिंदु कभी नहीं होता है। उन्हें सामान्य कॉल MyInterface.staticMethod () द्वारा निष्पादित नहीं किया जा सकता है। यदि आप कार्यान्वयन वर्ग MyImplementor.staticMethod () को निर्दिष्ट करके उन्हें कॉल करते हैं तो आपको वास्तविक वर्ग को अवश्य जानना चाहिए, इसलिए यह अप्रासंगिक है कि इंटरफ़ेस में यह शामिल है या नहीं।

सबसे महत्वपूर्ण बात यह है कि स्थैतिक विधियों को कभी भी ओवरराइड नहीं किया जाता है, और यदि आप ऐसा करने का प्रयास करते हैं:

MyInterface var = new MyImplementingClass();
var.staticMethod();

स्थिर के नियमों का कहना है कि घोषित प्रकार के var में परिभाषित विधि निष्पादित की जानी चाहिए। चूंकि यह एक इंटरफ़ेस है, यह असंभव है।

कारण आप निष्पादित नहीं कर सकते "परिणाम = MyInterface.staticMethod ()" यह है कि इसे MyInterface में परिभाषित विधि के संस्करण को निष्पादित करना होगा। लेकिन MyInterface में परिभाषित संस्करण नहीं हो सकता है, क्योंकि यह एक इंटरफ़ेस है। इसमें परिभाषा के अनुसार कोड नहीं है।

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


स्टेटिक विधियां उदाहरण विधियों की तरह आभासी नहीं हैं इसलिए मुझे लगता है कि जावा डिजाइनरों ने फैसला किया है कि वे उन्हें इंटरफेस में नहीं चाहते थे।

लेकिन आप कक्षाओं को इंटरफेस के अंदर स्थिर तरीकों से रख सकते हैं। आप कोशिश कर सकते हैं!

public interface Test {
    static class Inner {
        public static Object get() {
            return 0;
        }
    }
}

EDIT: As of Java 8, static methods are now allowed in interfaces. टिप्पणी EDIT: As of Java 8, static methods are now allowed in interfaces.

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


इंटरफ़ेस में स्थैतिक विधि की आवश्यकता क्या है, स्थिर तरीकों का उपयोग मूल रूप से किया जाता है जब आपको ऑब्जेक्ट का ऑब्जेक्ट पूरा करने की आवश्यकता नहीं होती है, इंटरफ़ेस के पूरे विचार को ओएसपी अवधारणाओं को अवधारणा से अलग करने वाली स्थिर विधि के परिचय के साथ लाने के लिए है।


Why can't I define a static method in a Java interface?

एक इंटरफ़ेस में सभी विधियां स्पष्ट रूप से सार हैं और इसलिए आप उन्हें स्थिर के रूप में परिभाषित नहीं कर सकते हैं क्योंकि स्थैतिक विधियां अमूर्त नहीं हो सकती हैं।





static-methods