JAVA : Accessing static method properly

2020-03-02 02:16发布

问题:

I am new to JAVA, and I like to try and understand everything.

When accessing a static method "hero.returnHp()" in JAVA, I have the following:

 hero Mike = new hero();

 Mike.returnHp();

The program runs fine, but I notice that Eclipse has a warning stating, "The static method from the type hero should be accessed in a static way." When I accept the auto-fix, it changes "Mike.returnHp();" to "hero.returnHp();".

So I have two questions:

1) What is the advantage of this?

2) If I created two objects of the same type, how would I specify which one to return when accessing in a static way?

Thanks!

回答1:

I would first like to point out what the keyword static means.

Static variables only exist once per class – that is, if you create a class with a static variable then all instances of that class will share that one variable. Furthermore, if it’s a public static variable, then anyone can access the variable without having to first create an instance of that class – they just call Hero.staticVariableName;

Static method/functions are stateless. That is, they act only on information (1) provided by arguments passed to the method/function, or (2) in static variables (named above), or (3) that is hard-coded into the method/function (e.g. you create a static function to return “hello” – then “hello” is hard-coded into the function).

The reason why Eclipse wants you to access static methods in a static way is because it lets you and subsequent programmers see that the method you’re accessing is static (this helps to prevent mistakes). The function will run either way you do it, but the correct way to do it is to access static functions in a static way. Remember that if you call a static method, no matter what instance variable you call it from (Tim.returnHp, Jim.returnHp, Mike.returnHp, whatever) you will call the same function from the hero class and you will see the exact same behavior no matter who you call it from.

If you created two objects of the same type then you COULD NOT specify which one to return when accessing in a static way; static functions/methods will refer to the entire Hero class.

Can you explain what you’re trying to do so that we can offer more specific feedback? It’s quite possible that returnHp() shouldn’t be static.

Is that “return hit points”? If it is, then you do NOT want it static because the number of hit points that a hero has is part of the hero’s state, and static methods are stateless. (Think of state like the current condition – alive, dead, wounded, attacking, defending, some combination of the aforementioned, etc.) I would recommend going into the Hero class and changing returnHp to a non-static method.

Now… I know you didn’t ask, but I would like to advise you of something:

Class names (such as Hero) should be capitalized. Instance variable names (such as mike) should be lowercase. This is a widely accepted naming convention and it will increase the readability of your code.

Jeff



回答2:

A static method is one which belongs to a class but not to an object. In your example above, you have created an object Mike of class hero. The method returnHp() is static, and belongs to the hero class, not the hero objects (such as Mike).

You will likely get an IDE or compiler warning when you reference a static method from an object, because it should never be tied to that object, only to its class.

Based on the method name, I would guess it shouldn't be static.

class hero {
    private float hp;
    public float returnHp() { // Should NOT be "public static float ..."
        return hp;
    }
}

The JavaDocs on class members has a brief discussion on statics as well. You may want to check that out.



回答3:

  1. It is part of the JVM spec.
  2. You don't need to. A static method is common between instances of a class, your confusion arises from thinking it is an instance method.


回答4:

A static method is completely independent of any instances of the class.

Consider that this works, and does not result in a NullPointerException:

 hero Mike = null;

 Mike.returnHp();

(by the way, class names should start with a capital, and variable names be lowercased).

Here is another neat example: Being a static method, Thread.sleep always sleeps the current thread, even if you try to call it on another thread instance.

The static method should be called by class name, not through an instance, because otherwise it is very confusing, mostly because there is no dynamic dispatch as static methods cannot be overridden in subclasses:

 hero Tim = new superhero(); // superhero extends hero

 Tim.returnHp();  // still calls the method in hero, not in superhero

You are getting a compiler warning now, but many people say that this was a design mistake and should be an error.



回答5:

static means a static way. One reason to use static is you can access it using class directly. that is its benefit. that is why main is always static. The entrance function don't need to create an instance first. Actually if you search static in google, and understand it deeply. U will know when and why use static.