views:

4901

answers:

17

Let's say I have a class designed to be instantiated. I have several private "helper" methods inside the class that do not require access to any of the class members, and operate solely on their arguments, returning a result.

public class Example {
   private Something member;

   public double compute() {
       double total = 0;
       total += computeOne(member);
       total += computeMore(member);
       return total;         
   }

   private double computeOne(Something arg) { ... }
   private double computeMore(Something arg) {... } 
}

Is there any particular reason to specify computeOne and computeMore as static methods - or any particular reason not to?

It is certainly easiest to leave them as non-static, even though they could certainly be static without causing any problems.

+7  A: 

My personal preference would be to declare them static, as it's a clear flag that they're stateless.

Steve B.
+9  A: 

It might result in slightly smaller bytecode, since the static methods won't get access to this. I don't think it makes any difference in speed (and if it did, it would probably be too small to make a difference overall).

I would make them static, since I generally do so if at all possible. But that's just me.


EDIT: This answer keeps getting downvoted, possibly because of the unsubstantiated assertion about bytecode size. So I will actually run a test.

class TestBytecodeSize {
    private void doSomething(int arg) { }
    private static void doSomethingStatic(int arg) { }
    public static void main(String[] args) {
        // do it twice both ways
        doSomethingStatic(0);
        doSomethingStatic(0);
        TestBytecodeSize t = new TestBytecodeSize();
        t.doSomething(0);
        t.doSomething(0);
    }
}

Bytecode (retrieved with javap -c -private TestBytecodeSize):

Compiled from "TestBytecodeSize.java"
class TestBytecodeSize extends java.lang.Object{
TestBytecodeSize();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

private void doSomething(int);
  Code:
   0:   return

private static void doSomethingStatic(int);
  Code:
   0:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   invokestatic    #2; //Method doSomethingStatic:(I)V
   4:   iconst_0
   5:   invokestatic    #2; //Method doSomethingStatic:(I)V
   8:   new     #3; //class TestBytecodeSize
   11:  dup
   12:  invokespecial   #4; //Method "<init>":()V
   15:  astore_1
   16:  aload_1
   17:  iconst_0
   18:  invokespecial   #5; //Method doSomething:(I)V
   21:  aload_1
   22:  iconst_0
   23:  invokespecial   #5; //Method doSomething:(I)V
   26:  return

}

Invoking the static method takes two bytecodes (byteops?): iconst_0 (for the argument) and invokestatic.
Invoking the non-static method takes three: aload_1 (for the TestBytecodeSize object, I suppose), iconst_0 (for the argument), and invokespecial. (Note that if these hadn't been private methods, it would have been invokevirtual instead of invokespecial; see JLS §7.7 Invoking Methods.)

Now, as I said, I don't expect there to be any great difference in performance between these two, other than the fact that invokestatic requires one fewer bytecode. invokestatic and invokespecial should both be slightly faster than invokevirtual, since they both use static binding instead of dynamic, but I have no idea if either is faster than the other. I can't find any good references either. The closest I can find is this 1997 JavaWorld article, which basically restates what I just said:

The fastest instructions will most likely be invokespecial and invokestatic, because methods invoked by these instructions are statically bound. When the JVM resolves the symbolic reference for these instructions and replaces it with a direct reference, that direct reference probably will include a pointer to the actual bytecodes.

But many things have changed since 1997.

So in conclusion... I guess I'm still sticking with what I said before. Speed shouldn't be the reason to choose one over the other, since it would be a micro-optimization at best.

Michael Myers
Two downvotes and no comments? Interesting...
Michael Myers
all these negative votes for what seems like a very straightforward answer. +1 in the interests of truth, justice, ....
Steve B.
Thanks. (Although I could have deleted it and gotten a badge while it was at -3. :D )
Michael Myers
maybe your guess that it is smaller bytecode is wrong? i'm +1'ing to set the universe right, at least until someone can show a reason for -3.. :)
Kip
The JIT compiler will anyways inline and optimize them, so the amount of bytecode instructions has little to do with how fast it will be.
Esko Luontola
That's why I said "I don't think it makes any difference in speed (and if it did, it would probably be too small to make a difference overall)."
Michael Myers
I really hate downvotes without comments. I kinda think you should be forced to enter a comment or add to someone elses comment/downvote. Not because I don't like downvotes, but because I want to know what I said that someone else takes exception to.
Bill K
+19  A: 

I prefer such helper methods to be "private static". That will make it clear to the reader that they will not modify the state of the object (and my IDE will show calls to static methods in italics, so I will know it is static without looking a the signature).

Esko Luontola
+1  A: 

The static/non-static question comes down to "will I really need to use an object of this class"?

So, are you passing the object between different methods? Does the object contain information that is useful outside the context of the static methods? Is there any reason not to define methods both ways if you'll use them both ways?

If you're in this dilemma, it seems to me that you have all of the data required for the method floating around in your code outside of the object. Is this what you want? Would it be easier to just always collect that data into an object each time? You might just be ambivalent about committing to a single model. If you can do it all using one way, then pick either static or non-static and go with it.

notnot
+6  A: 

I can't really think of clear advantages for private static method. That being said, there is no specific advantages to making them non-static either. It's mainly a matter of presentation : you might want to make them static to clearly underline the fact that they are not altering an object.

For method with different access privileges, I think there are two main arguments :

  • static methods can be called without creating an instance of an object, which can be useful
  • static methods can't be inherited, which can be a problem if you need polymorphism (but is irrelevant for private methods).

Besides that, the difference is pretty small, and I strongly doubt that the extra this pointer passed to instance method makes a significant difference.

Axelle Ziegler
The advantage of not making it static is that someone can subclass and override the method's behavior.
Clint Miller
Clint its a private method so you cannot override the method.
Bhushan
Exactly, for private method I don't think it makes much of a difference. For public methods, however, I agree with what you're saying
Axelle Ziegler
A: 

More specifically to the example you've given, it seems that the purpose of defining these methods is more for code clarity when you're reading it than for functionality (they are defined as private). In that case, going with static really does nothing for you, since the purpose of static is to expose class functionality.

notnot
This little answer, buried under a load of other answers, really touches the essence of the matter: class level functionality vs. object level functionality.
eljenso
Thanks, el, I really appreciate it. I wouldn't mind a little vote up, either :)
notnot
I did give it a +1 at the time I wrote the comment.
eljenso
I disagree. Code clarity is still important for private methods. It may be less important but it's still something to strive for.
+1  A: 

If the method is basically just a subroutine that will never foreseeably use state information, declare it static.

This allows it to be used in other static methods or in class initialization, i.e.:

public class Example {
   //...

   //Only possible if computeOne is static
   public final static double COMPUTED_ONE = computeOne(new Something("1"));

   //...
}
Kip
A: 

My preference in cases like these is to make computeOne and computeMore static methods. The reason: encapsulation. The less code which has access to the implementation of your class, the better.

In the example you give, you state that computeOneand computeMore shouldn't need to access the internals of the class, so why give the opportunity for maintainers of the class to meddle with the internals.

Andy
A: 

I would declare them as static to flag them as stateless.

Java does not have a better mechanism for minor operations that aren't exported, so I think private static is acceptable.

Uri
+10  A: 

The answer is... it depends.

If member is an instance variable specific to the object you're dealing with, then why pass it as a parameter at all?

For instance:

public class Example {
   private Something member;

   public double compute() {
       double total = 0;
       total += computeOne();
       total += computeMore();
       return total;         
   }

   private double computeOne() { /* Process member here */ }
   private double computeMore() { /* Process member here */ } 
}
R. Bemrose
+1: The example was really bad.
E Dominique
+1: Even though the example is bad, too many methods that COULD be static is a bad code smell. By the way, static methods are actually funcitons, they are not at all OO. They may belong as a method in another class, or you may be missing a class that this function could belong to as a method.
Bill K
A: 

One reason you might want to declare static helper methods is if you need to call them in the class constructor "before" this or super. For example:

public class MyClass extends SomeOtherClass { 
    public MyClass(String arg) {
       super(recoverInt(arg));
    }

    private static int recoverInt(String arg) {
       return Integer.parseInt(arg.substring(arg.length() - 1));
    }
}

This is a bit of a contrived example but clearly recoverInt cannot be an instance method in this case.

oxbow_lakes
you can call an instance method in the constructor, but if you're delegating to another constructor with super(...) or this(...), you can't call an instance method until after the delegation (but statics are ok as you point out)
Kip
I've edited the post to make this clearer
oxbow_lakes
+1  A: 

or any particular reason not to [declare them as static]?

Yes.

By keeping them as instance methods, you allow your self to provide a different implementation later.

It may sound silly ( and actually it would be if those methods are used only by you in a 50 line program) but in larger applications, or in libraries used by someone else, you may decide to choose a better implementation, but don't want to breake existing code.

So, what you do, is create a subclass and return that in the new versions, since the methods were declared as instance methods, you'll let polymorphism do its job.

Addtionally you could benefit from making the contructor private and provide an static factory method for the same reason.

So, my recomendation is, keep them as instance methods, and avoid static if possible.
Take advantage of the dynamism the language provides.

See here for a somehow related video: How to design a good API and why it matters

Although it is not directly related with the "statis vs instance" methods, it touches some interesting points in API design.

OscarRyz
Completely agree. I usually try to avoid statics and privates altogether for just this reason. I think that most of the other answers have missed the point.
Clint Miller
We're talking about *private* helpers, which means they are not part of the public API of the class. That means nothing at all prevents you from providing a different implementation later, making them non-static, or making any other changes.
Jonik
Aaaahmm... that's a good point Jonik. Still, creating a good habit should be enough reason ( subjectively speaking of course )
OscarRyz
Completely dis-agree. There is not good reason you would want to change a private method without changing the class in which it is defined. The only way to do what you suggest is by byte-code manipulation.
Peter Lawrey
What you suggest could make sense if the method were not private, but even then I would suggest you design based on a current needed rather than designing based on an imagined need.
Peter Lawrey
+2  A: 

I would like to clarify few things which other posters have said as its giving wrong information.

Firstly since the methods are private even if you declare them static you will not be able to access them outside of this class. Secondly they are private so you can not even override in subclass so static or non-static doesn't make any difference. Thirdly a non-static private method can be called from a constructor of the class also, it need not be static.

Now coming to your question if a private helper method should be defined as static or non-static. I will go with Steve's answer as marking a private method static shows that this method is stateless as I also follow this rule when I code.

Bhushan
but there are places where only a static method can be called, like in my example and in Chris Marshall's example
Kip
Yes Kip your and Chris answer's are correct. I have not commented on those as they are correct answers. I only talked about wrong answers.
Bhushan
+1  A: 

One reason is that, all else being equal, static method calls should be faster. Static methods cannot be virtual, and do not take an implicit this reference.

dsimcha
See my answer below (I added the analysis after it was already at -3, so it's not very visible).
Michael Myers
A: 

What is meant by stateless methods? Please some one explain it for me. Because I am making class variables and methods only if it is necessary.

A method that doesn't read from or modify (non-constant) members.
A: 

As many people said, make it is as a static! Here's the thumb rule which I follow : If you think the method is just a mathematical function i.e it is stateless, doesn't involve any instance variables(=> no blue color vars [in eclipse] in the method), and the result of the method will be the same for 'n' number of calls (with the same parameters, ofcourse), then mark that method as STATIC.

And if you think that this method will be useful to other class then move it to a Util class otherwise, put the method as private in the sameclass. (minimizing the accessibility)

HanuAthena
A: 

Off-Topic: I'd keep the helper methods in a standalone utility/helper class with only static methods in it.

The trouble with having helper methods at the point of use ( read 'same class' ) is that someone down the line may just choose to post their own unrelated helper methods in the same place

Everyone
-1: SO is not a messaging forum. You'll do better by actually asking a proper question.
Stu Thompson