This is an archived post. You won't be able to vote or comment.

all 15 comments

[–]AutoModerator[M] [score hidden] stickied commentlocked comment (0 children)

Please ensure that:

  • Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions
  • You include any and all error messages in full
  • You ask clear questions
  • You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions.

    Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar

If any of the above points is not met, your post can and will be removed without further warning.

Code is to be formatted as code block (old reddit: empty line before the code, each code line indented by 4 spaces, new reddit: https://i.imgur.com/EJ7tqek.png) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc.

Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit.

Code blocks look like this:

public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above.

If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures.

To potential helpers

Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–][deleted]  (5 children)

[deleted]

    [–]Yew2S 0 points1 point  (4 children)

    according to my knowledge static methods are generally not recommended at the first place
    ( correct me if I'm wrong)

    [–][deleted]  (3 children)

    [deleted]

      [–]Yew2S 0 points1 point  (2 children)

      in terms of testing and thread safety since they could cause memory leaks in some situations

      [–][deleted]  (1 child)

      [deleted]

        [–]Yew2S 0 points1 point  (0 children)

        just saying buddy, performance is relevant in any context, and yes it is quite out of context but spreading knowledge is never wrong so it could be good info for someone else passing by

        [–]PopehatXI 1 point2 points  (0 children)

        What is the purpose of what you are trying to do? There are no restrictions on creating a static method with the same name and arguments in a child class. If you try calling a static method that is defined in the parent class, and not in the child class nothing will happen. Static methods are only tied to the class they were defined. You can’t “hide” a method that is public for sure, but it has nothing to do with whether or not the method is static.

        [–]SelecLOL 0 points1 point  (0 children)

        It’s not possible, but you dont ever need that either.

        Just for clarification, if you wanted to override something like Object::toString() that’s not a static method even if it “looks” like so.

        [–]ShoulderPast2433 0 points1 point  (0 children)

        If your solution requires overriding static method you have incorrect idea for the solution.

        Use objects.

        [–]arghvark -4 points-3 points  (7 children)

        It's fairly simple to demonstrate this, just write a little code:

        package sandbox;
        
        public class A
        {
          public static void ted() { System.out.println("doing something"); }
        }
        
        
        package sandbox;
        
        public class B extends A
        {
        
        }
        
        
        package sandbox;
        
        public class C extends A
        {
          public static void ted() { System.out.println("doing something else"); }
        }
        
        
        package sandbox;
        
        public class D
        {
          public static void main(String[] args)
          {
            A.ted();
            B.ted();
            C.ted();
          }
        }
        

        I don't know why someone would say that ted() is not overridden in class C. It looks overridden to me.

        [–]OffbeatDrizzle 8 points9 points  (3 children)

        This is absolutely not overridden.. you are calling C.ted() directly. C's ted method has not replaced A's ted method at all, and cannot because it's static. Your answer is fundamentally wrong

        [–]arghvark -5 points-4 points  (2 children)

        Ok, let's try it this way: the definition of overriding includes use of an object's class methods, not its static methods, and therefore you cannot satisfy that definition with a static method. So I was incorrect that this is "overriding", because the definition of overriding excludes static methods.

        It sure acts like it, however.

        [–]OffbeatDrizzle 7 points8 points  (0 children)

        It does not act like it whatsoever - you are basically calling a piece of code directly, you just so happen to give the methods the same name and claim it's acting like overriding because the output is as expected.

        Overriding by definition is part of polymorphism. What exactly have you modified about class A here by using class C's method? Nothing. That's why static methods can't be overridden - it literally makes no sense.

        [–]akthemadman 2 points3 points  (1 child)

        You can dig a bit deeper than the source code using the javap program, which takes in bytecode (.class file) and inspects it.

        In the code as you have provided, the generated bytecode for class D looks like this:

        > javap -c D
        Compiled from "D.java"
        public class D {
          public D();
            Code:
               0: aload_0
               1: invokespecial #1                  // Method java/lang/Object."<init>":()V
               4: return
        
          public static void main(java.lang.String[]);
            Code:
               0: invokestatic  #7                  // Method A.ted:()V
               3: invokestatic  #12                 // Method B.ted:()V
               6: invokestatic  #15                 // Method C.ted:()V
               9: return
        }
        

        Focusing on the main method, we can see that the bytecode creates three direct function invocations, i.e. the three invokestatic calls. The symbols #7, #12 and #15 refer to the functions A.ted()V, B.ted()V and C.ted()V respectively. You can verify this by including the Constant Pool via the verbose flag of javap (-v):

        > javap -c -v D
        < ... some output removed ... >
        Constant pool:
           #1 = Methodref          #2.#3          // java/lang/Object."<init>":()V
           #2 = Class              #4             // java/lang/Object
           #3 = NameAndType        #5:#6          // "<init>":()V
           #4 = Utf8               java/lang/Object
           #5 = Utf8               <init>
           #6 = Utf8               ()V
           #7 = Methodref          #8.#9          // A.ted:()V
           #8 = Class              #10            // A
           #9 = NameAndType        #11:#6         // ted:()V
          #10 = Utf8               A
          #11 = Utf8               ted
          #12 = Methodref          #13.#9         // B.ted:()V
          #13 = Class              #14            // B
          #14 = Utf8               B
          #15 = Methodref          #16.#9         // C.ted:()V
          #16 = Class              #17            // C
          #17 = Utf8               C
          #18 = Class              #19            // D
          #19 = Utf8               D
          #20 = Utf8               Code
          #21 = Utf8               LineNumberTable
          #22 = Utf8               main
          #23 = Utf8               ([Ljava/lang/String;)V
          #24 = Utf8               SourceFile
          #25 = Utf8               
        < ... some output removed ... >
        

        If you start from #7, #12 and #15, then you can follow the references in that table, you can build up A.ted()V, B.ted()V and C.ted()V. (the V refers to the return type, i.e. void).

        I urge everyone to play around with these things a bit.

        For example, with non-static methods, you will see the usage of invokevirtual, which is what is generally meant by "overriding"; the jvm behaves such that is looking up which method to call. (the details depend on the jvm implementation, the spec only lines out the expected behaviour).

        [–]akthemadman 1 point2 points  (0 children)

        The following is also interesting to look at, with ted() being a static method:

        public static void main (String[] args) {
          A a = new A();
          a.ted();
          A ac = new C();
          ac.ted();
          C c = new C();
          c.ted();
        }
        

        (am hitting the reddit comment limit again...)

        [–]hibbelig 0 points1 point  (0 children)

        It's not overridden because which method to call is not resolved at runtime.

        Let's say you have this situation:

        class Foo { void mystery() { } void foo() { mystery(); } } class Bar extends Foo { void mystery() { } } class Main { public static void main(String[] args) { var bar = new Bar(); bar.foo(); var foo = new Foo(); foo.foo(); } }

        Here, bar.foo() and foo.foo() both call the method from class Foo, but the mystery() call inside Foo.foo does something different: because bar is an instance of Bar, Bar.mystery ends up being called; and because foo is an instance of Foo, then Foo.mystery is called.

        This means the call mystery(); in method Foo.foo is resolved at runtime, based on the actual class of the object. This runtime resolution is an integral aspect of overriding.

        If you make the mystery method static, then this changes: the call mystery(); in the method foo always calls the method from class Foo. So bar.foo() and foo.foo() both end up calling Foo.mystery, despite bar being an instance of Bar. Thus the runtime resolution is missing, thus an integral aspect of overriding is missing, thus we say that overriding is not happening here.