2011-03-05 13 views
18
class A { 
    public static void foo() {} 
} 

class B { 
    public static void foo() {} 
} 

के माध्यम से एक स्थिर विधि का उपयोग कैसे करें मेरे पास Class clazz = A.class; or B.class है;कक्षा संदर्भ

मैं कैसे "clazz" के माध्यम से इस का उपयोग करते हैं यह सोचते हैं यह सौंपा जा सकता है या तो 'ए' या 'बी'

उत्तर

28

यह उपयोग करने वालों के तरीकों का उपयोग करने में ही संभव है प्रतिबिंब। आप कक्षा को सीधे संदर्भित नहीं कर सकते हैं, केवल कक्षा का एक उदाहरण।

आह्वान करने के लिए methodName (int एक, स्ट्रिंग ख) प्रतिबिंब का उपयोग करें:

Method m = clazz.getMethod("methodname", Integer.class, String.class); 
m.invoke(null, 1, "Hello World!"); 

देखें Class.getMethod() और Method.invoke()

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

5

आप वर्ग के लिए एक स्पष्ट संदर्भ के बिना स्थिर तरीकों का उपयोग नहीं कर सकते हैं।

यहाँ कोई विरासत, खेद है, तो आप या तो कार्य करें:

Object o = .... // eith an A or B instance. 
if(o instanceof A) { 
    A.foo() 
} else { 
    B.foo() 
} 
:

A.foo() 

या

B.foo() 

तुम सच में इसकी जरूरत है, तो आप एक चेक करना होगा

लेकिन आप केवल उन कार्यों को फ़ंक्शन उदाहरण क्यों नहीं बनाते हैं, और उन्हें एक इंटरफ़ेस लागू करने देते हैं?

ठीक है, आपके पास कक्षा वस्तु है। तो फिर कार्य करें:

Class c = ...; 
c.getMethod("foo").invoke(null); // null to invoke static methods 
+0

लेकिन क्लैज में 'ए' या 'बी' का संदर्भ नहीं है। इसका मतलब यह है कि ऐसा करना संभव नहीं है। – user339108

+0

@ user339108, दुर्भाग्य से नहीं, –

+0

के अच्छे तरीके से नहीं, मेरे पास मूल रूप से इंटरफेस के लिए लिखा गया तर्क था और मेरे व्युत्पन्न वर्ग ('ए' या 'बी') को तत्काल नहीं किया जा सकता क्योंकि उन्हें आंतरिक कक्षाओं के रूप में परिभाषित किया गया था और उनके पास नहीं था सार्वजनिक वर्ग पहचानकर्ता, इसलिए मुझे इस तकनीक का सहारा लेना पड़ा। – user339108

9

आप इस तरह प्रतिबिंब के माध्यम से एक स्थिर विधि आह्वान कर सकते हैं:

Method method = clazz.getMethod("methodname", argstype); 
Object o = method.invoke(null, args); 

कहाँ argstype तर्क प्रकार और आर्ग की एक सरणी है कॉल के लिए मानकों की एक सरणी है। निम्नलिखित लिंक पर अधिक जानकारियां:

आपके मामले में, कुछ इस तरह काम करना चाहिए:

Method method = clazz.getMethod("foo", null); 
method.invoke(null, null); // foo returns nothing 
+1

आप पिछले दो पंक्तियों में अंतिम 'शून्य' को छोड़ सकते हैं, क्योंकि उन विधियों को अब var-args विधियों के रूप में घोषित किया गया है। –

+0

मुझे यह स्पष्ट लगता है, लेकिन यह इंगित करने के लिए एक अच्छी बात है। – krtek

0

ज्ञान की कमी के अनुसार अनुरोधित निर्माण की आवश्यकता इस तथ्य से दी गई है कि एक इंटरफ़ेस स्थिर सार विधियों की संभावना प्रदान नहीं करता है।

public enum Cheese implements Yumy { 
    GOUDA(49), 
    ESROM(40), 
    HWARTI(38); 
    private int percentage; 
    private Cheese(int fat100) {...} constructor 
    public void yamyam() {...} // as in Yumy 
    public static Cheese getByFat(int fat100) {...} // no chance to be part 
                of interface 
}; 
0

मुझे आशा है कि यह भी कई मान्यताओं बना रही है नहीं या अपने प्रश्न से बहुत दूर भी घूम, लेकिन अपने दो वर्गों एक आम महाप्रकार साझा करते हैं और उदाहरण बनाकर तो संतोषजनक है अगर आप कर सकते हैं:

यहाँ एक उदाहरण है
  1. एक आम इंटरफेस
  2. लागू वस्तु का एक उदाहरण बना myClass.newInstance() के माध्यम से (कक्षा एक खाली निर्माता होनी चाहिए)
  3. कॉल उदाहरण वस्तु से स्थिर विधि।


interface Foo { 
    void foo(); 
} 
class A implements Foo {...} 
class B implements Foo {...} 

<T extends Foo> public void something(Class<T> clazz) { 
    T myInstance = clazz.newInstance(); 
    myInstance.foo(); 
} 

... 
something(A.class); 

यह थोड़ा विचित्र है, लेकिन मेरे मामले में यह उपयोगी साबित हुई, और मैं बहुत ही प्रश्न है कि तुमने किया था पूछकर शुरू कर दिया।

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