views:

544

answers:

10

Hi,

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?

Martijn

+2  A: 

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.

Confusion
+2  A: 

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?

tangens
+6  A: 

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().

zedoo
Possible, but not recommended. See this answer http://stackoverflow.com/questions/1932625/java-return-class-not-an-instance/1933573#1933573
Alexander Pogrebnyak
wow. this is surprising..
zedoo
+1  A: 

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();
    } 
}
Bozho
+5  A: 

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

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?

Peter Lawrey
+3  A: 

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.

Chad Okere
A: 

Not an answer as such but...

Scala uses singleton objects in place of static methods (which really aren't very object oriented).

If you were to use Scala then you very much could do this sort of thing

Kevin Wright
+1  A: 
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.

irreputable
+1 for finding this loophole in Java. -1 for not throwing a word of caution that this should not be done. BTW, Eclipse generates this warning when compiling this code `The static method blah() from the type A should be accessed in a static way`.
Alexander Pogrebnyak
`org.apache.commons.cli.OptionBuilder` uses this anti-pattern of calling static methods on returned instances.
Alexander Pogrebnyak
This is not a loophole in Java. It is just an example that is not doing what you think it is doing. See my answer.
Stephen C
+2  A: 

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 (I hope) illustrates why this approach doesn't solve the OP's problem.

Stephen C