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

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

我有Class clazz = A.class; or B.class;如何通過類引用訪問靜態方法

如何通過「clazz所」訪問此假設它可以分配無論是「A」或「B」

回答

28

只可能通過訪問這些方法反射。您不能直接引用類,只能引用Class類型的實例。

使用反射來調用方法名(INT一,字符串二):

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

Class.getMethod()Method.invoke()

你可能要重新考慮你的設計,以避免需要動態調用靜態方法。

5

您不能訪問靜態方法沒有明確提及類。

無繼承這裏,對不起,讓您必須做的:

A.foo() 

B.foo() 

如果你真的需要它,你必須做的檢查:

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

但是,爲什麼你不只是讓這些函數實例函數,並讓他們實現一個接口?

Okey,你有一個類對象。然後做:

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

但不clazz有'A'或'B'的參考。這是否意味着它無法做到這一點。 – user339108 2011-03-05 09:56:34

+0

@ user339108,不幸的是,沒有一個好的方式 – 2011-03-05 09:59:13

+0

我有最初爲接口編寫的邏輯,我的派生類('A'或'B')不能被實例化,因爲它們被定義爲內部類並且沒有公共類標識符,因此我不得不採取這種技術。 – user339108 2011-03-05 10:00:06

9

您可以通過反射調用靜態方法是這樣的:

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

哪裏argstype是參數類型和args數組是爲調用參數數組。以下鏈接更多的信息:

在你的情況,這樣的事情應該工作:

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

您可以將最後兩行的空值留給最後兩行,因爲現在這些方法被聲明爲var-args方法。 – 2011-03-05 11:17:46

+0

我覺得這樣更清楚,但指出這點很好。 – krtek 2011-03-05 11:24:39

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); 

這是一個有點怪異,但在我的情況下,它被證明是有用的,我開始問,你做了同樣的問題。