2012-01-23 20 views
25

बस प्रयोग से मैंने पाया कि जावा गैर स्थैतिक विधियां स्थिर संदर्भ पर भी सभी समान विधियों को ओवरराइड करती हैं। पैरामीटर अधिभार की अनुमति के बिना भी।जावा स्थैतिक आयात

import java.util.Arrays;  
import static java.util.Arrays.toString; 

public class A { 
    public static void bar(Object... args) { 
     Arrays.toString(args); 
     toString(args);  //toString() in java.lang.Object cannot be applied to (java.lang.Object[]) 
    } 
} 

मुझे इस बारे में कुछ भी नहीं मिल रहा है। क्या यह एक बग है? यदि ऐसा नहीं है, तो इस तरह की भाषा को लागू करने के कोई कारण हैं?

यूपीडी: जावा 6 इस उदाहरण को संकलित न करें। सवाल यह है - क्यों?

+0

ऐसा लगता है कि यह अपने सुपर ऑब्जेक्ट के 'टूस्ट्रिंग() ' –

+2

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

+0

@ जिगर जोशी, यह ऐसा लगता है। लेकिन मुझे इसके बारे में कुछ भी नहीं मिला। और अधिक, हम स्थिर संदर्भ से 'Object.toString' को कॉल नहीं कर सकते हैं इसलिए मुझे इस व्यवहार में कोई तर्क नहीं दिख रहा है। –

उत्तर

21

स्पष्टीकरण सरल है, हालांकि यह सच है कि व्यवहार अत्यधिक unintuitive है परिवर्तन नहीं करता है:

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

अब यहां क्या हो रहा है यह है कि toString() विधि वाला सबसे छोटा संलग्न क्षेत्र कक्षा ए है जो इसे Object से प्राप्त करता है। इसलिए हम वहां रुकते हैं और आगे की खोज नहीं करते हैं। अफसोस की बात यह है कि संकलक दिए गए दायरे में विधियों का सबसे अच्छा फिट खोजने की कोशिश करता है और नोटिस करता है कि वह उनमें से किसी को भी कॉल नहीं कर सकता है और एक त्रुटि देता है।

जिसका मतलब है कभी नहीं स्थिर आयात एक ऐसा नाम है जो वस्तु में एक विधि के समान है साथ तरीकों, क्योंकि तरीकों कि दायरे में स्वाभाविक रूप से कर रहे हैं स्थिर आयात अधिक महत्व दिया जाता (JLS विस्तार से विधि छाया का वर्णन करता है, लेकिन इस के लिए समस्या मुझे लगता है कि इसे याद रखना बहुत आसान है)।

संपादित करें: @alf कृपया जेएलएस का सही हिस्सा सबमिट करें जो describes the method invocation उन लोगों के लिए है जो पूरी तस्वीर चाहते हैं। यह अपेक्षाकृत जटिल है, लेकिन फिर समस्या सरल नहीं है, इसलिए इसकी अपेक्षा की जा सकती है।

+4

जेएलएस लिंक, आपको इसकी आवश्यकता होनी चाहिए - http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.12.1 – alf

+0

@ आधा धन्यवाद, जो अब एक बेहतर जवाब देता है । अगर मैं जानता हूं कि जेएलएस में इसके लिए विवरण कहां मिलना है तो मैं इसे खुद जोड़ दूंगा। – Voo

4

यह ओवरराइड नहीं है। अगर यह काम करता है, तो this.toString()Arrays.toString के बजाय A की विधि तक पहुंच जाएगा, अगर ओवरराइडिंग होने पर मामला होगा।

language specification बताते हैं कि स्थिर आयात केवल static तरीके और प्रकार के संकल्प को प्रभावित:

पैकेज पी का एक संकलन इकाई ग में एक एकल स्थैतिक आयात घोषणा घ है कि एक क्षेत्र छाया n नामित आयात करता है सी में एक स्थैतिक आयात पर ऑन-डिमांड घोषणा द्वारा आयातित किसी भी स्थैतिक क्षेत्र की घोषणा, पूरे सी।

पैकेज पी का एक संकलन इकाई ग में एक एकल स्थैतिक आयात घोषणा घ कि एक विधि नामित n हस्ताक्षर रों छाया के साथ की घोषणा हस्ताक्षर रों आयातित के साथ किसी भी स्थिर विधि नामित n आयात करता है एक स्थिर-आयात द्वारा सी में मांग की घोषणा, पूरे सी।

पैकेज पी का एक संकलन इकाई ग में एक एकल स्थैतिक आयात घोषणा घ कि एक प्रकार n नामित की घोषणाओं छाया का आयात करता है:

  • किसी भी स्थिर प्रकार एक स्थिर आयात द्वारा n नामित आयातित सी में मांग की घोषणा
  • कोई शीर्ष स्तर का प्रकार (§7.6) नामित एक अन्य संकलन इकाई (§7.3) पी में घोषित किया गया।
  • कोई टाइप नाम एन सी में आयात-पर-मांग घोषणा (§7.5.2) द्वारा आयात किया गया। पूरे सी।

स्थिर आयात गैर स्थैतिक तरीकों या आंतरिक प्रकारों को छाया नहीं देते हैं।

तो toString गैर स्थैतिक विधि को छाया नहीं करता है। चूंकि नाम toStringA की गैर-स्थैतिक विधि का संदर्भ ले सकता है, यह Arrays की विधि का संदर्भ नहीं दे सकता है और इस प्रकार toStringtoString नामक एकमात्र विधि से बांधता है जो दायरे में उपलब्ध है, जो String toString() है। वह विधि कोई तर्क नहीं ले सकती है ताकि आपको संकलन त्रुटि मिल सके।

Section 15.12.1 विधि संकल्प बताते हैं और पूरी तरह से static तरीकों लेकिन अंदर नहीं member तरीकों भीतर अनुपलब्ध विधि के नाम की छाया अनुमति देने के लिए फिर से लिखा गया है करने के लिए होगा।

मेरा अनुमान है कि भाषा डिजाइनर विधि संकल्प नियमों को सरल रखना चाहते थे, जिसका अर्थ है कि वही नाम एक ही बात है जिसका अर्थ है कि यह static विधि में दिखाई देता है या नहीं, और केवल एक ही चीज जो बदलती है।

+0

सिवाय इसके कि विधि 'बार' स्थिर है, इसलिए – chrisbunney

+0

@StasKurilin पर 'toString() 'को आमंत्रित करने के लिए कोई उदाहरण नहीं है। –

+2

@StasKurilin [par। 6.3.1] (http://java.sun.com/docs/books/jls/third_edition/html/names.html#34133) इसे और स्पष्ट रूप से समझाता है। यह कहता है कि आवृत्ति विधि 'ऑब्जेक्ट .toString() 'छाया * किसी भी अन्य विधियों * के दायरे में घोषणा। इसमें 'Arrays.toString (ऑब्जेक्ट []) 'के लिए स्थिर आयात शामिल है। इसका मतलब है कि, प्रभावी रूप से, स्थिर आयात * कोई प्रभाव नहीं है * - संकलक विधि कॉल को हल करने के लिए भी विचार नहीं करेगा। – millimoose

0

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

1

आप निम्नलिखित समान कोड देख तो आप किसी भी संकलक त्रुटि

import static java.util.Arrays.sort; 
public class StaticImport { 
    public void bar(int... args) { 
     sort(args); // will call Array.sort 
    } 
} 

कारण यह संकलित नहीं जाएगा कोशिश करते हैं और तुम्हारा कि toString() (या किसी अन्य विधि में परिभाषित किया गया है नहीं है, तो क्लास ऑब्जेक्ट) ऑब्जेक्ट क्लास के लिए अभी भी स्कॉप्ड हैं क्योंकि ऑब्जेक्ट आपकी कक्षा के माता-पिता हैं। इसलिए जब संकलक ऑब्जेक्ट क्लास से उन विधियों के मिलान हस्ताक्षर को पाता है तो यह कंपाइलर त्रुटि देता है। मेरे उदाहरण में ऑब्जेक्ट क्लास में sort(int[]) विधि नहीं है इसलिए संकलक सही ढंग से स्थिर आयात के साथ मेल खाता है।

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