Java: Return class (Not an instance)

2020-06-03 04:57发布

问题:

Is it possible to return in a static method a class? I will explain...

I have:

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

I want to create a static method in B witch returns A. So you can do:

A.blah();

And

B.getA().blah();

This, without creating an instance of A. Just use it static methods.

Is this possible?

回答1:

This is a rebuttal of @irreputable's answer:

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

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

It "works", but probably not in the sense that you expect, and certainly not in a useful way. Let's break this down into two parts:

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

The first statement is returning a (null in this case) instance of A, and the second statement is ignoring that instance and calling A.blah(). So, these statements are actually equivalent to

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

or (given that getA() is side-effect free), just plain

A.blah();

And here's an example which illustrates this more clearly:

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".

... and this (I hope) illustrates why this approach doesn't solve the OP's problem.



回答2:

I'm going to guess that the reason you ask this is that you want B to return many different classes with different behaviours - not just A.

You probably want to use an interface for what you're doing instead.

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:

No this is not possible. You have two options:

  1. B.getA() returns an instance of A, and blah() will be a non-static method.

  2. Directly call A.blah().



回答4:

People are saying it's impossible, and that's kind of true, but if you use the reflection API you can do something close to that.

Here's how you could do it.

You have a class that does this.

public class B { 
   Class a
   public static Class getA(){
      return a; 
    }
}

then to call blah you do:

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
}

So, why would you want to do this? Well, if you do it this way you can change the class A at So getA() could return A, B, C or D, all with different blah() functions. I'm not really sure what purpose that would serve, but if you want to do it, you can.

see: Class.getDeclaredMethod() and Method.invoke() for more info.

I haven't tried this, so you might need to do some tweaking.



回答5:

No, this is not possible. You can only return a reference to an instance of a class. The closest you can get to this is to return a reference to a variable of type Class. The question is: why do you want this? What problem are you trying to solve? There may be a better solution.



回答6:

Even if it would be possible, it won't be of much use. The call A.blah() doesn't create an instance of A. It's a static method with no need for an instance.

And you can't use interfaces to implement static methods. So what should it be good for?



回答7:

If you don't want to have an instance of A, then let B call blah() directly. I.e.

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


回答8:

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

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

EDIT

It is true that it is equivalent to

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

Except they look quite different. Imagine you have a chain of these.

I checked out org.apache.commons.cli.OptionBuilder and personly I wouldn't do it that way, but the author has his case. The API is used only in the beginning of a program, in a single thread.

API designers sometimes have to make some magic moves, don't be too judgemental.



回答9:

You can return a Method using reflection which you can invoke() later. However, it sounds like you are trying to do something which should be done another way. Why are you trying to do this?