participate


Java Programming - Calling static method.
This question is answered.

<<   Back to Forum  |   Give us Feedback
This topic has 10 replies on 1 page.
Rocksolid99
Posts:9
Registered: 11/4/09
Calling static method.   
Nov 4, 2009 6:03 AM
 
 
Hi all,
I've some confusion over how the static method is called. Please have a look at following code:
class A{
             public static void abc{
                    ........
             }
}
 
public class B extends A{
             public static void main(String a[]){
                     A refA = new B();
                     refA.abc();                                //This will call class A's static method.
 
                     B refB = new B();
                     refA.abc();                                //This will call class B's static method.
                     
                     new B().abc();                          //This will call class B's static method.
             }
             public static void abc{
                    ........
             }
}


Now as they say 'Static method should be accessed in static way', which i think means using the class name and without creating any object. As we can see in above code, can we say that the static method checks for the reference variable and not the object while making a call. If it is so, then why does it allow to make a call on object(new B().abc())???

I'd appreciate if anyone could help me with the same?
 
endasil
Posts:2,767
Registered: 10/12/07
Re: Calling static method.   
Nov 4, 2009 6:20 AM (reply 1 of 10)  (In reply to original post )
 
 
Rocksolid99 wrote:
Now as they say 'Static method should be accessed in static way', which i think means using the class name and without creating any object. As we can see in above code, can we say that the static method checks for the reference variable and not the object while making a call. If it is so, then why does it allow to make a call on object(new B().abc())???

I'd appreciate if anyone could help me with the same?
It's less that "it uses the reference variable" and more that it "uses the inferred type." For instance, try:
((B)refA).abc();

I haven't tested it, but I'd guess it would call B.abc() since you're casting, even though the reference variable is an A.

When you do a new B(), it has an inferred type of B.

But yes, a good example of why to never reference a static member through a reference.
 
Rocksolid99
Posts:9
Registered: 11/4/09
Re: Calling static method.   
Nov 4, 2009 7:04 AM (reply 2 of 10)  (In reply to #1 )
 
 
Hey endaisl,
Thanks for your time. But i am still not there.

When we say something like;

((B)refA).abc();

Aren't we just downgrading the refA here. And hence creating a virtual reference of Class B? If this is true, can't we say that the calling to static methods is done with ref variable?
Please let me know if i am missing out on something here.

It would be great if you could throw some more light on 'inferred' thing. What exactly is that?

Thanks in advance.
 
baftos
Posts:2,524
Registered: 11/16/99
Re: Calling static method.   
Nov 4, 2009 7:13 AM (reply 3 of 10)  (In reply to original post )
 
 
Rocksolid99 wrote:
Hi all,
I've some confusion over how the static method is called. Please have a look at following code:
class A{
             public static void abc{
                    ........
             }
}
 
public class B extends A{
             public static void main(String a[]){
                     A refA = null;
                     refA.abc();                                //This will call class A's static method.
 
                     B refB = null;
                     refB.abc();                                //This will call class B's static method.
                     
                     new B().abc();                          //This will call class B's static method.
             }
             public static void abc{
                    ........
             }
}

I changed your code a bit. Check what happens!
 
dcminter
Posts:9,319
Registered: 3/4/99
Re: Calling static method.   
Nov 4, 2009 7:16 AM (reply 4 of 10)  (In reply to #2 )
Helpful
 
can't we say that the calling to static methods is done with ref variable

This is a compile time decision. In the bytecode call to the static method the variable is completely ignored. So all that matters is what's true about the type of the reference at compile time. The value of the variable is completely irrelevant.
 
georgemc
Posts:16,804
Registered: 5/8/06
Re: Calling static method.   
Nov 4, 2009 7:16 AM (reply 5 of 10)  (In reply to #2 )
Helpful
 
Rocksolid99 wrote:
Hey endaisl,
Thanks for your time. But i am still not there.

When we say something like;

((B)refA).abc();

Aren't we just downgrading the refA here. And hence creating a virtual reference of Class B? If this is true, can't we say that the calling to static methods is done with ref variable?

The compiler recognises that it's a static method, and replaces your reference with a reference to the class upon which the static method is declared. Try it. Run it through a decompiler.
 
Rocksolid99
Posts:9
Registered: 11/4/09
Re: Calling static method.   
Nov 4, 2009 7:35 AM (reply 6 of 10)  (In reply to #5 )
 
 
Hey Thanks ppl,
That was really informative. :)
 
endasil
Posts:2,767
Registered: 10/12/07
Re: Calling static method.   
Nov 4, 2009 8:16 AM (reply 7 of 10)  (In reply to #2 )
 
 
Rocksolid99 wrote:
It would be great if you could throw some more light on 'inferred' thing. What exactly is that?
It was probably a mistake to use that terminology, since inferred type already has a very different meaning in dynamically-typed languages. What I meant was that the Java compiler infers the type of an expression, and uses that to replace the static call.

Here's a fun one. What do you think will be printed from this code?

public class StaticMethod {
   public static void main(String[] args) {
      (true ? new Concrete1() : new Concrete2()).print();
   }
}
 
class Base {
   public static void print() {
      System.out.println("Base");
   }
}
 
class Concrete1 extends Base {
   public static void print() {
      System.out.println("Concrete1");
   }
}
 
class Concrete2 extends Base {
   public static void print() {
      System.out.println("Concrete2");
   }
}


What about if Concrete2 extended Concrete1 instead?

Then it gets really messy if StaticMethod is defined in a different source file, Concrete2 is changed to extend Concrete1, but only Concrete2's source file was recompiled. Then StaticMethod will likely continue printing "Base", but then when you recompile StaticMethod (even though you made no change) it will afterward print "Concrete1".

There's really no excuse not to just completely avoid this mess and always use the classname explicitly. Personally, it strikes me as odd that the Java language designers even allowed a static invocation from a non-static context. It's just opening the door to confusion and danger.
 
baftos
Posts:2,524
Registered: 11/16/99
Re: Calling static method.   
Nov 4, 2009 9:22 AM (reply 8 of 10)  (In reply to #7 )
 
 
My guess why thy allow this: refactoring a method from instance to static would not break calling code.
Why refactor? Perhaps because you find out that no object state is involved, so you might as well make it static.
I don't say it's good or bad, just trying to guess why.
 
dcminter
Posts:9,319
Registered: 3/4/99
Re: Calling static method.   
Nov 4, 2009 9:34 AM (reply 9 of 10)  (In reply to #8 )
 
 
My guess why thy allow this: refactoring a method from instance to static would not break calling code.

I'm skeptical. My own pet theory is that it makes something in the compiler easier to implement. That's a WAG too though and may well be wrong.

Either way I think it was a mistake.

Edited by: dcminter on 04-Nov-2009 17:33
 
endasil
Posts:2,767
Registered: 10/12/07
Re: Calling static method.   
Nov 4, 2009 9:58 AM (reply 10 of 10)  (In reply to #8 )
 
 
baftos wrote:
My guess why thy allow this: refactoring a method from instance to static would not break calling code.

Class1.java:
public class Class1 {
   public void method() {
      System.out.println("Hello, world!");
   }
}


Class2.java:
public class Class2 {
   public static void main(String[] args) {
      Class1 c1 = new Class1();
      c1.method();
   }
}


$ javac Class1.java Class2.java
$ java Class2
Hello, world!
$ vim Class1.java #at this point I edit method() to be static
$ javac Class1.java
$ java Class2
Exception in thread "main" java.lang.IncompatibleClassChangeError: Expecting non-static method
Class1.method()V
at Class2.main(Class2.java:5)
$ javac Class2.java
$ java Class2
Hello, world!


In other words, the compiled Class2 is expecting an instance method. You can't change one without at the very least recompiling the other. So the calling code breaks.

Edited by: endasil on 4-Nov-2009 12:57 PM
 
This topic has 10 replies on 1 page.
Back to Forum
 
Read the Developer Forums Code of Conduct

Click to email this message Email this Topic

Edit this Topic
  
 
 
Forums Statistics

About Sun forums
  • Sun Forums is a large collection of user generated discussions. It is here to help you ask questions, find answers, and participate in discussions.

    Check out our guide on Getting started with Sun Forums for a full walkthrough of how to best leverage the benefits of this community.

Powered by Jive Forums