16

Can we call a static method without mentioning the class name in Java?

polygenelubricants
  • 348,637
  • 121
  • 546
  • 611
user315459
  • 165
  • 1
  • 1
  • 3
  • 2
    Care to explain a bit more about what you mean by that? I can think offhand of at least three *utterly different* interpretations... – Donal Fellows Apr 13 '10 at 13:52

5 Answers5

35

Yes you can. Check out static imports. You have to mention the class name in the import statement, but after that you don't have to.e.g. from the linked article:

import static java.lang.Math.abs;
import static java.lang.Math.max;

int xDist = abs(destination.getX() - x);
int yDist = abs(destination.getY() - y);
return max(xDist, yDist);

Introduced in Java 5.

Brian Agnew
  • 254,044
  • 36
  • 316
  • 423
20

Yes, you can call a static method without mentioning the class name. There's the import static (see JLS 7.5.4 for exact mechanism), but even without it, if the name can be resolved (see JLS 15.12.1 for exact mechanism) without fully qualifying the class, it will work.

The following code compiles and prints "Hello world!" as expected.

import static java.lang.System.out;

public class Test {
   static String greeting() {
      return "Hello world!";
   }
   public static void main(String[] args) {
      out.println(greeting());
   }
}

out in the println statement is actually a static field access of the class java.lang.System, not a static method, but it's a static member access nonetheless. greeting() is a static method invocation, and the class name can be omitted since its reference can be resolved without fully qualifying the name.


Now let's ask if this is a good idea. Unless you're calling a static method from within its class, IT'S NOT a good idea generally to omit the class name!!!

Let's focus on static import first. A quote from the guide:

So when should you use static import? Very sparingly! Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). In other words, use it when you require frequent access to static members from one or two classes. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Readers of your code (including you, a few months after you wrote it) will not know which class a static member comes from. Importing all of the static members from a class can be particularly harmful to readability; if you need only one or two members, import them individually. Used appropriately, static import can make your program more readable, by removing the boilerplate of repetition of class names.

The case is made stronger by the following example:

class Base {
    void task1() {
        System.out.println("Base.task1");
    }
    static void task2() {
        System.out.println("Base.task2");
    }
}

class Child extends Base {
    void task1() {
        System.out.println("Child.task1");          
    }
    static void task2() {
        System.out.println("Child.task2");
    }       
}

//....
Base sweetChildOMine = new Child();
sweetChildOMine.task1(); // prints "Child.task1"
sweetChildOMine.task2(); // prints "Base.task2"

What a surprise! You'd think that since sweetChildOMine has a reference to an instance of Child, sweetChildOMine.task2() should print "Child.task2" because it's overridden by Child class, right?

WRONG! A static method can not be overridden! It can only be hidden by a subclass! In fact, if you tried to do the right thing and add the @Override annotation to task2, it would not compile!

From JLS 15.12.4.4 Locate method to invoke:

If the invocation mode is static, no target reference is needed and overriding is not allowed. Method m of class T is the one to be invoked.

In fact, this problem is covered in Java Puzzlers Puzzle 48: All I Get Is Static. The conclusion given at the end of the puzzle is this:

In summary, qualify static methods invocations with a class name, or don't qualify them at all if you're invoking them from within their own class, but never qualify them with an expression. Also, avoid hiding static methods. Together, these guidelines help eliminate the misleading appearance of overriding with dynamic dispatch for static methods.

It is best to follow all these recommendations together, so:

  • If you're calling a static method within its own class, don't qualify
  • Otherwise, qualify with the class name
    • If you're doing this a lot within one class, consider static import of that specific method
      • Try not to static import all members with *
    • Never qualify with an expression
  • Don't hide a static method; you can't @Override it, it'll only cause confusion

See also:

Community
  • 1
  • 1
polygenelubricants
  • 348,637
  • 121
  • 546
  • 611
0

Yes, adding to Brian Agnew you can call static methods through an instance of that class type as well.

GuruKulki
  • 24,340
  • 43
  • 131
  • 192
  • Hrm? `...without mentioning the class name` – wheaties Apr 13 '10 at 13:00
  • I disagree that it's not a good idea. There are certain types of commands that really should be static. When using those commands, if you want to allow for different implementations, passing in an instance of the class that implements the method is the only reasonable way. Of course, it would be considerably more convenient if Java had the ability to pass in a class type and (easily) call one of it's static methods. – RHSeeger Apr 13 '10 at 13:01
  • 2
    I agree that this is not a good idea but just wanted to say this is also possible. – GuruKulki Apr 13 '10 at 13:17
0

Yes you can call a static method without the class name. For example, if you are calling it within another static method of the same class.

public class TestStatic{

static void hello()
{
   System.out.println("Hello World");
}
static void hello2()
{
   hello();
   System.out.println("Welcome to java");
}
public static void main(String[] args)
{
   hello2();
}

}

Abimbola
  • 854
  • 6
  • 5
0

Yes.

class CallStaticMethodTest { 
   public static void staticMethodOne() {
       System.out.println("Static method one");
   }

   // Invoke from a non-static method
   public void instanceMethodOne() {
        staticMethodOne();// Calling static method without mentioning the class name 
   }

   // Invoke from another static method:
   public static void staticMethodTwo() {
       staticMethodOne();
  }
}  
OscarRyz
  • 184,433
  • 106
  • 369
  • 548