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

不,这是不可能的。 你有两个选择:

  1. B.getA()返回A的实例,而blah()将是一个非静态方法。

  2. 直接打电话给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返回一个方法,您可以稍后调用它。 然而,听起来你正在尝试做一些应该以另一种方式做的事情。 你为什么要这样做?