Java:返回类(不是实例)
是否可以在静态方法中返回一个类? 我会解释…
我有:
public class A { public static void blah(){} } public class B { }
我想在B中创建一个静态方法返回A
所以你可以这样做:
A.blah();
和
B.getA().blah();
这样,无需创建A
的实例。 只需使用它静态方法。
这可能吗?
这是对@ irreputable的答案的反驳:
public class B { public static A getA(){ return null; } } B.getA().blah(); //works!
它“有效”,但可能不是你所期望的,当然也不是有用的。 我们将其分为两部分:
A a = B.getA(); a.blah();
第一个语句返回A的(在这种情况下为null)实例,第二个语句忽略该实例并调用A.blah()
。 所以,这些陈述实际上相当于
B.getA(); A.blah();
或者(鉴于getA()
是无副作用的),只是简单
A.blah();
这是一个更清楚地说明这一点的例子:
public class A { public static void blah() { System.err.println("I'm an A"); } } public class SubA extends A { public static void blah() { System.err.println("I'm a SubA"); } } public class B { public static A getA(){ return new SubA(); } } B.getA().blah(); //prints "I'm an A".
……而这(我希望)说明了为什么这种方法无法解决OP的问题。
我猜你问这个问题的原因是你希望B返回许多不同的行为 – 不仅仅是A.
您可能希望使用接口来代替您所做的事情。
interface IA { void blah(); } public class B { IA getA1() { return new IA { void blah() { ...code... } } } IA getA2() { ... } IA getA3() { ... } } myCallingMethod { B.getA1().blah(); B.getA2().blah(); B.getA3().blah(); }
不,这是不可能的。 你有两个选择:
-
B.getA()
返回A的实例,而blah()
将是一个非静态方法。 -
直接打电话给
A.blah()
。
人们说这是不可能的,这是真的,但是如果你使用reflectionAPI,你可以做一些接近它的事情。
这是你如何做到的。
你有一个这样做的课程。
public class B { Class a public static Class getA(){ return a; } }
然后打电话给你做:
try{ Method m = B.getA().getDeclaredMethod("blah"); m.invoke(null);//for a static method, you can invoke on null } Catch(Exception e){ // see documentation for list of exceptions }
那么,你为什么要这样做呢? 好吧,如果你这样做,你可以改变A类,所以getA()可以返回A,B,C或D,所有这些都有不同的blah()函数。 我不确定会有什么用途,但如果你想这样做,你可以。
有关详细信息,请参阅: Class.getDeclaredMethod()和Method.invoke() 。
我没试过这个,所以你可能需要做一些调整。
不,这是不可能的。 您只能返回对类实例的引用。 您可以得到的最接近的是返回对Class类型变量的引用。 问题是:你为什么要这样? 你想解决什么问题? 可能有更好的解决方案。
即使有可能,它也没什么用处。 调用A.blah()
不会创建A
的实例。 它是一个静态方法,不需要实例。
并且您不能使用接口来实现静态方法。 那么它应该有什么好处呢?
如果你不想拥有A
的实例,那么让B
直接调用blah()
。 即
class B { void blah() { A.blah(); } }
public class B { public static A getA(){ return null; } } B.getA().blah(); //works!
编辑
确实,它等同于
B.getA(); A.blah();
除了他们看起来完全不同。 想象一下,你有一系列这些。
我检查了org.apache.commons.cli.OptionBuilder
并且我不会这样做,但作者有他的情况。 API仅在程序的开头使用,在单个线程中使用。
API设计师有时必须做出一些神奇的动作,不要过于评判。
您可以使用reflection返回一个方法,您可以稍后调用它。 然而,听起来你正在尝试做一些应该以另一种方式做的事情。 你为什么要这样做?