2011-03-05 63 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); 

这是一个有点怪异,但在我的情况下,它被证明是有用的,我开始问,你做了同样的问题。