Why Isn't Calling a Static Method by Way of an Instance an Error For the Java Compiler

Why isn't calling a static method by way of an instance an error for the Java compiler?

Basically I believe the Java designers made a mistake when they designed the language, and it's too late to fix it due to the compatibility issues involved. Yes, it can lead to very misleading code. Yes, you should avoid it. Yes, you should make sure your IDE is configured to treat it as an error, IMO. Should you ever design a language yourself, bear it in mind as an example of the kind of thing to avoid :)

Just to respond to DJClayworth's point, here's what's allowed in C#:

public class Foo
{
public static void Bar()
{
}
}

public class Abc
{
public void Test()
{
// Static methods in the same class and base classes
// (and outer classes) are available, with no
// qualification
Def();

// Static methods in other classes are available via
// the class name
Foo.Bar();

Abc abc = new Abc();

// This would *not* be legal. It being legal has no benefit,
// and just allows misleading code
// abc.Def();
}

public static void Def()
{
}
}

Why do I think it's misleading? Because if I look at code someVariable.SomeMethod() I expect it to use the value of someVariable. If SomeMethod() is a static method, that expectation is invalid; the code is tricking me. How can that possibly be a good thing?

Bizarrely enough, Java won't let you use a potentially uninitialized variable to call a static method, despite the fact that the only information it's going to use is the declared type of the variable. It's an inconsistent and unhelpful mess. Why allow it?

EDIT: This edit is a response to Clayton's answer, which claims it allows inheritance for static methods. It doesn't. Static methods just aren't polymorphic. Here's a short but complete program to demonstrate that:

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

class Derived extends Base
{
static void foo()
{
System.out.println("Derived.foo()");
}
}

public class Test
{
public static void main(String[] args)
{
Base b = new Derived();
b.foo(); // Prints "Base.foo()"
b = null;
b.foo(); // Still prints "Base.foo()"
}
}

As you can see, the execution-time value of b is completely ignored.

Is calling static methods via an object bad form ? Why?

The bad form comment comes from the Coding Conventions for Java

See http://www.oracle.com/technetwork/java/codeconventions-137265.html#587

The reason for it, if you think about it, is that the method, being static, does not belong to any particular object. Because it belongs to the class, why would you want to elevate a particular object to such a special status that it appears to own a method?

In your particular example, you can use an existing integer through which to call parseInt (that is, it is legal in Java) but that puts the reader's focus on that particular integer object. It can be confusing to readers, and therefore the guidance is to avoid this style.

Regarding this making life easier for you the programmer, turn it around and ask what makes life easier on the reader? There are two kinds of methods: instance and static. When you see a the expression C.m and you know C is a class, you know m must be a static method. When you see x.m (where x is an instance) you can't tell, but it looks like an instance method and so most everyone reserves this syntax for instance methods only.

Can't access static field via `super` from within subclass?

super refers to the parent class of the actual object. In the main method there is nothing like "actual object" because it is a static scope.

The Superclass's attribute text is defined as static so you can access it throught it class name inside the static main method.

Don't you confound class with object (or instance).

What is the reason behind non-static method cannot be referenced from a static context ?

You can't call something that doesn't exist. Since you haven't created an object, the non-static method doesn't exist yet. A static method (by definition) always exists.

Android: Why does makeText work with Toast instance?

Because static methods and variables can also by accessed from an instance of the class

However, accessing them that way is considered bad practice

Why are non-static references to static variables compilable?

this is a valid reference to an instance of Everything. As such, it is a valid reference to the Everything class, and therefore a valid way of accessing any static member and/or method of that class.

You can even do:

Everything nothing = null;
nothing.answer; // Does not throw an NPE!!

Generally, this is not very good practice... IDEA, for instance, will warn you that you "access a static member via an instance reference".



Related Topics



Leave a reply



Submit