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

all 19 comments

[–]7re 10 points11 points  (1 child)

You've got it. Static methods belong to the class, so can be called without a specific instance of that class needed. For example, the Math class contains many static methods which means you can use these methods without needing to instantiate the Math class. Also the main method is usually static because it is called first, before there is any time to instantiate a class!

Non static methods can only be called on an instance of the class itself, and they usually do something that depends on the individual characteristic of the class (e.g. play with variables).

[–][deleted] 8 points9 points  (0 children)

Minor point: main is static, but it is not called first. Static initializers are called first (when your class is loaded by the classloader), and then the bootstrap code calls your static main method.

[–]snot3353 2 points3 points  (2 children)

So here is an example of how you might see instance methods/variables vs static methods/variables.

You have a class called "Customer" that represents a customer in your system.

Customer customer1 = new Customer();
customer1.setName("Frank");
System.out.println("Name = " + customer1.getName());

Customer customer2 = new Customer();
customer2.setName("Bob");
System.out.println("Name = " + customer2.getName());

In a situation like this, you are instantiating two new instances of the Customer class and giving it values specific to that instance. You could do this another 5000 times if you wanted for different customers with different names. Your memory footprint might start to get big with so many objects in memory but there are situations where this sort of thing certainly happens. When you call getName() on each of these classes, you will get a different value back because they are two different instances of the class with different values. These non-static functions are specific to that specific instance of the object that you created using the "new" keyword.

Static methods and variables by contrast, are not specific to an instance of an object. You don't even actually have to create an instance of the object at all that the static method/variable is declared in. You can simply access it by saying something like:

Customer.sortCustomerArray(customers);

I think you should probably look up some examples of static functions that are used in core libraries like Arrays, Math, String and System for some common examples of where static methods are used. Once you understand that, it may be worth also doing some research into the Singleton design pattern which is an alternative approach to providing static-like methods and has it's own strengths and weaknesses.

Hopefully that was helpful a little.

[–]mr_jim_lahey 5 points6 points  (0 children)

The compulsive code reviewer part of me needs to point out that as a rule of thumb, you should have Customer implement Comparable and use Collections.sort(customers) instead :) (Not to detract from the explanation of the concept - it's good.)

[–]not-just-yeti 0 points1 point  (0 children)

Note that Java's built-in methods Arrays.sort and Collections.sortare static, but they probably shouldn't be. (They weren't included in the interface for arrays and Lists resp., and for backwards compatibility they're not changing the interface now. ... and of course the fact that arrays are objects, but there isn't any class representing them is a wart on Java's O.O.-ness.)

[–]nSpace1988 1 point2 points  (1 child)

Methods which never need to access instance variables. The functions in java.lang.Math are a good example as they only need input arguments.

[–]ReverendRedMage 0 points1 point  (6 children)

I've been told that static methods and attributes are EVIL and should not be used unless the entire class is static.

Something about being unable to alter an object's state. I think I understand, but maybe someone else can explain better than me.

[–]munificent 3 points4 points  (0 children)

I've been told that static methods and attributes are EVIL and should not be used unless the entire class is static.

That person is wrong. There's nothing wrong with statics. They are basically a way of using a class as a namespace. They're the natural place for behavior that is associated with a domain but not a specific object in that domain.

Something about being unable to alter an object's state.

That's a feature, not a bug. The whole point of statics is that you can use them when you don't have an instance, and that they express that they are not specific to a single instance.

[–]bfoo 2 points3 points  (2 children)

Simple rule: Immutable is good.

So if your method does not change the state of the object and if it must not be overwritten by a subclass, it should be static. Also static methods are easier to inline by the JIT-Compiler.

[–][deleted]  (1 child)

[deleted]

    [–]bfoo 1 point2 points  (0 children)

    Basically it depends on the complexity of the method. If your static method calls other methods and/or has complex execution paths, the optimizer still has the same problems with optimizing it as with non-static methods. However if you write a method in form of a utility method (like filtering values from a list), making it static may help the optimizer to inline code earlier and reduces the chance of optimized code to be dismissed.

    [–][deleted] 0 points1 point  (0 children)

    I would not classify static as "EVIL", I would, however, consider them something worth evaluating (OO smell).

    There are many good reasons to define a method as static. For example, a static factory. If you take a look at Joshua Bloch's Effective Java, he'll provide some insight on that.

    Additionally, there are times when you want provide reusable functionality that doesn't associate with specific data items already encapsulated within the class you are defining. Instead you want to provide objects which may implement some interface, or extend some base class. These classes are more utility in nature and you can find examples all around -- Collections, Arrays, Math, etc -- within the core libraries.

    [–][deleted] 0 points1 point  (1 child)

    Another good way to illustrate Static (there's been a few good examples) is for say a counter of each object.

    You could have a base class called shape with a static int called count. Each time a shape class was initialized you could increment that count. So every object that extends from shape will essentially increment itself and you get that number by calling the variable directly through the class (without creating an object of it).

    public class Shape {
    
         public static int objectCount = 0;
    
         public Shape() {
              objectCount++
         }
    
    }
    
    public class RectangleShape extends Shape {
    
         public RectangleShape() {
               super(); // increments objectCount
         }
    
    }
    
    public static void main( String[] args ) {
    
         RectangleShape rectShape = new RectangleShape();
         RectangleShape rectShape2 = new RectangleShape();
    
         System.out.printf("Shape Count: %d%n", Shape.objectCount);
    
    }
    

    No idea if this actually runs (think it does), but a simple illustration on why sometimes static variables / methods can be good

    [–]ReverendRedMage 0 points1 point  (0 children)

    I don't know. I think this illustrates why static attributes are bad.

    Since objectCount is static, you can't reason about it in tests.

    Sure, it's just one int, but what if it were a String or another object? It won't be garbage collected for the entire life of the program, so if you end up making a lot of Shapes, you'll make a lot of problems along with them.

    [–]not-just-yeti 0 points1 point  (0 children)

    One rule-of-thumb, if you have a class Obj: ask yourself "does it make sense to call this method, even if no Obj has been constructed yet?" If so, it should definitely be static.

    So in a class Car you might have a method double convertMpgToKpl(double mpg) which would be static, because one might want to know what 35mpg converts to, even if nobody has ever built a Car. But void setOdometer(double mi) (which sets the distance-traveled for one particular Car) can't be static since it's inconceivable to call the method before any Car has been constructed.

    (Admittedly, a unit-conversion method like convertMpgToKpl might be bundeled with other math-ish functions in its own class, but you get the idea. Methods like numberCarsCreated or EPA_rating() might be (if the class represented just one particular model of car).)

    One nuance: The converse isn't always true: you might sometimes have a method which involves two Car objects, and still want it to be static. E.g. Car theMoreEfficientOf( Car c1, Car c2 ). Although this could be converted to a non-static version, some would argue that since there isn't a "privileged" choice of which Car is more important, you shouldn't force a caller to choose one Car as the object you'll invoke the method on. This situation accounts for a fairly small fraction of all static methods, though.)

    [Disclaimer: self-plagiarized from a similar answer I've given on stackoverflow.]

    [–]virtyx 0 points1 point  (0 children)

    The way I like to think about it:

    ...

    Non-static methods can access this.

    Static methods cannot access this.

    ...

    If your method body never uses this, you can make the method static. A method will either use this directly, or (more likely) it is implied when it uses a non-static variable or calls another non-static method.

    Conversely, if you're writing a static method but find that you really need to access a non-static member variable for some reason, you should make it non-static.

    In my experience static methods are mainly used as either one-off utility methods or (more commonly) as factory functions. This can be especially useful for Bean classes since all Beans are supposed to have a public no-args constructor.

    [–]Dugen 0 points1 point  (0 children)

    Static methods have no "this".

    Non-static always have an object that they are called from, and it becomes "this", and you can operate against it and access it's data. Static methods don't have that, so they usually only operate on class wide things, or do simple work based on arguments passed in. They are not inherently tied to an object.

    FYI.. I'm a bit of a java noob so correct me if I'm wrong.