Java:返回类(不是实例)

时间:2009-12-19 11:08:35

标签: java static class-design return-value

是否可以在静态方法中返回一个类?我会解释......

我有:

public class A { public static void blah(){} }
public class B { }

我想在B女巫返回A中创建一个静态方法。所以你可以这样做:

A.blah();

B.getA().blah();

这不用创建A的实例。只需使用静态方法。

这可能吗?

9 个答案:

答案 0 :(得分:7)

这是对@ 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的问题。

答案 1 :(得分:6)

不,这是不可能的。您有两种选择:

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

  2. 直接致电A.blah()

答案 2 :(得分:6)

我猜你问这个问题的原因是你希望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();
}

答案 3 :(得分:4)

人们说这是不可能的,而有点是真的,但是如果你使用反射API,你可以做一些接近它的事情。

这是你如何做到的。

你有一个这样做的课程。

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()了解详情。

我没试过这个,所以你可能需要做一些调整。

答案 4 :(得分:2)

不,这是不可能的。您只能返回对类实例的引用。您可以得到的最接近的是返回对Class类型变量的引用。问题是:你为什么要这样?你想解决什么问题?可能有更好的解决方案。

答案 5 :(得分:2)

即使有可能,它也没什么用处。调用A.blah()不会创建A的实例。这是一个静态方法,不需要实例。

并且您不能使用接口来实现静态方法。那么它应该有什么好处呢?

答案 6 :(得分:1)

如果您不想拥有A的实例,请让B直接致电blah()。即。

class B { 
    void blah() { 
        A.blah();
    } 
}

答案 7 :(得分:1)

public class B { 
    public static A getA(){ return null; }
}

B.getA().blah(); //works!

修改

确实相当于

B.getA();
A.blah();

除了他们看起来完全不同。想象一下,你有一系列这些。

我检查了org.apache.commons.cli.OptionBuilder而且我不会这样做,但作者有他的理由。 API仅在程序的开头使用,在单个线程中使用。

API设计师有时必须做出一些神奇的举动,不要过于评判。

答案 8 :(得分:0)

您可以使用反射返回一个方法,您可以稍后调用它。 然而,听起来你正在尝试做一些应该以另一种方式做的事情。 你为什么要这样做?