tags:

views:

1110

answers:

23

Say you're writing method foo() in class A. foo doesn't ever access any of A's state. You know nothing else about what foo does, or how it behaves. It could do anything.

Should foo always be static, regardless of any other considerations? Why not?

It seems my classes are always accumulating many private helper methods, as I break tasks down and apply the only-write-it-once principle. Most of these don't rely on the object's state, but would never be useful outside of the class's own methods. Should they be static by default? Is it wrong to end up with a large number of internal static methods?

A: 

If foo() doesn't have anything to do with Object A then why is the method in there?

Static methods should still be relevant. If there isn't anything going on then why have you written a method that has no association with it?

Josh K
It's gotta live somewhere...and it's only ever used by A.
Tom Tresansky
To be fair, since this is Java, the method has to go _somewhere_. In many projects I've done we keep around a `Util` class which only contains static methods that don't interact with any state. Java doesn't have global anything, after all.
Brian S
If it's only ever used by static methods in A, then it should be static. Otherwise, it shouldn't. That doesn't make a good reason for it to be static by default.
Rodrigo Gama
@Tom Tresansky It should also be used by your unit testing code. You have thorough unit tests, right? (This is the 21st century.)
Tom Hawtin - tackline
@Tom Tresansky: So it's their best bet to stay where they are. If you are breaking methods down most probably they will have some arguments. If you find that these arguments are used by more then one function it's good to make fields out of them. That adds dependency on A's state and it's considered a good practice since your method calls are shorter. I found it controversial at first, but some od the TDD books highly recommend it. Plus you get an optimization for free - each method call doesn't require new big stack (to copy arguments) and JIT might inline them.
Rekin
This doesn't address the question.
quixoto
@Tom Hawtin: I generally try to write unit tests against the public interface only. How the class is implemented doesn't worry me so much at the unit-testing stage.
Tom Tresansky
@Tom Tresansky If the code is in its own method, then that about the size I would want to be testing at. Therefore, factor it out into a different module [class], and test the default access ("package private") interface.
Tom Hawtin - tackline
+3  A: 

If it does nothing with objects of this class, but actually belong to this class (I would consider moving it elsewhere), yes it should be static.

Mchl
+1 for considering moving it elsewhere.
ILMTitan
Although awesome in theory, there are quite a few times that you just need to refactor a few lines of redundant code that follow a pattern but are extremely functional. That said, you are not wrong--seriously TRY to make sure you use methods instead of functions and that your methods are correctly placed.
Bill K
+6  A: 

No. Never. Static methods should be an exception. OO is all about having Objects with behaviour which revolves around the object's state. Imho, ideally, there shouldn't be any (or very few) static methods, because everything unrelated to the object's state could (and to avoid leading the concept of an object ad absurdum, should) be placed in a plain old function at module level. Possible exception for factories because Complex.fromCartesian (to take a wikipedia example) reads so well.

Of course this (edit: Module-level functions) isn't possible in a single-paradigm OO language (edit: like Java) - that's why I'm such a devoted advocate of multi-paradigm language design, by the way. But even in a language exclusively OO, most methods will revolve around the object's state and therefore be nonstatic. That is, unless your design has nothing to do with OO - but in this case, you're using the wrong language.

delnan
@delnan: -1 Java has no plain old functions at module level.
Tom Tresansky
I know. I even wrote that in my answer. Read the second paragraph again.
delnan
@delnan: Sorry, that didn't make it clear to me that you were talking about module-level functions and the Java language. I found it ambiguous and thought someone else might be confused. Edit it and I'll undownvote.
Tom Tresansky
I hope it's clearer now.
delnan
Much. Thank you. I know if I was reading this a few years ago, I would have been off and searching for module-level functions in Java, thinking that would solve all my problems...
Tom Tresansky
Some good points, but I disagree with avoiding static methods *because* you are using Java. As Steve McConnell would say, you don't want to code *in* a language so much as code *into* a language.
Justin Ardini
@Justin Ardini: Yes, of course static methods should be an exception in any language, not just in Java.
delnan
@delnan + @Justin Ardini: Aren't methods which don't involve object state not only useful, but desirable: easier to test, easier to understand behaviour, etc.? Of course the overall design of an OO project should be an OO one, which necessarily involves state, but once you start breaking your algorithms down, don't your OO methods eventually start calling sub-procedures which could care less about state? This has been my typcial experience. I don't understand the general hostility to static methods I'm seeing here, which is at the core of what I'm trying to investigate with this question.
Tom Tresansky
@Tom: I'm with you 100%! Personally, I'm all for static methods. I don't think they should be default in Java, but they are certainly easy to test and maintain. Where I agree with delnan is that in OOP, many methods will be closely tied to objects, which is perfectly fine as long as the object has a clear and cohesive purpose.
Justin Ardini
To paraphrase you: Implementing everything as a stateful object has downsides, so decoupling algorithms from objects is sometimes worthwhile (and static methods are the only way Java gives us to do so). I wholeheartedly agree. But static methods are not really "methods" in that they are an object's behaviour, they are just functions, which may or may not be related to some class. In pure OO, they have no place. That doesn't mean that static methods are bad, it just means they have no place in pure OO - and it means pure OO isn't perfect. But in an OO language, all design should be *mostly* OO.
delnan
delnan: You're just begging the question. Tom's asking "given that Java doesn't have module-level functions, should a function that doesn't use any of the object's state be static unless given a good reason otherwise?" Your answer doesn't seem to address that.
Gabe
@Gabe: A static method *is a* (pun intended) method not using an object's state, so the answer would obviously be yes.
delnan
@delnan: your answer (above) seems to unequivocally say "no. never." yet just above this comment, when presented with the OP's question again, you say "obviously yes". since you seem to grok the OP's question, at least here in the comments, i'd suggest you edit your answer to clarify. thanks.
quixoto
What do you mean by "a plain old function at module level"? If you mean "a function that doesn't depend on an object's state", then Java has a modifier for that: "static".
Jay
I don't see how there's anything anti-OOP about using static functions. @delnan seems to be saying that now that we have the power of OOP at our disposal, we should never use anything non-OOP. But that's like saying that because you have a way-cool power drill, you should never use a screwdriver. Use each tool where it's appropriate. Don't throw away all your old tools just because you bought a new one.
Jay
@quixoto: Ouch. It's late (at least here, UTC+1). I meant to append something along the lines of: "... Except that in an OO language, by far most methods are supposed to nonstatic." I.e. since the least methods (in an OO design) could implicitly become static, it's not worth the hassle.
delnan
@Jay: I agree 100% to "Don't throw away all your old tools just because you bought a new one", but, well, Java is OO. Is your design isn't very OO, that's fine - most of mine aren't either - but I strongly suggest you implement it in a language which supports the paradigms your design uses. Programming in an [abritary paradigm] language but mostly using other paradigms is insane. If you're programming in an OO language, then for crying out loud, do OOP - or switch to another language. Of course static methods are fine occasionally.
delnan
@delnan: Sorry, didn't mean for that to be a jab. I think your comments reflect a clearer understanding of the OP's question (which is actually quite nuanced) than your actual answer does. Since this is currently the highest-rated answer, and it doesn't really address the question, I'd encourage you to amend it.
quixoto
@delnan: I don't think making certain helper functions static is "mostly using other paradigms". I think in the OP's case, static methods are fine. He mentioned specifically broken down helper functions that don't relate to object state. They added `static` just for this purpose in Java.I think people are mistaking the OP's intent as wanting to make gigantic parts of his classes static.
Chimmy
-1 for being completely wrong. See Jay's answer for details, and really avoid declaring that any language feature should never be used.
Erick Robertson
@Erick: Would you please tell me where I said they should *never* be used? I'm with the "All general statements false (except this one)" crew, so if I wrote something else, I'd like to correct that.
delnan
"No. Never. Static methods should be an exception." It's the first words of your answer.
Erick Robertson
Is my answer really that unclear? I thought it was quite obvious that "No. Never." refered to "Should Java methods be static by default?", while the rest was the rationale behind that answer. Especially, since "Never" and "should be an Exception" would be contrary when applied to the same thing...
delnan
@delnan: RE what your "No never" referred to. Okay, I take back some of the nasty things I've been saying about you! I think the text of the OP question had very different connotations from the title.
Jay
+1  A: 

Don't use static if you can avoid it. It clashes with inheritance ( overriding ).

Also, not asked but slightly related, don't make utility methods public.

As for the rest, I agree with Matt b. If you have a load of potentially static methods, which don't use state, just put them in a private class, or possibly protected or package protected class.

extraneon
These are private methods, they won't be inherited.
Tom Tresansky
If X does not play well together with inheritance, it's usually not a sign that X is bad, but inheritance.
Willi
A: 

If it's only ever used by methods in A and wouldn't have any use outside it, then it should be static (and, probably, be placed in a Helper Class. It doesn't have any use outside A now, but there's no guarantee it will never have. Otherwise, it shouldn't.

If it doesn't have anything to do with the state of A, it could be useful at other places...

Anyway, that doesn't make a good reason for Java methods to be static by default.

Talking about this last issue, they shouldn't be static by default, because having to write 'static' make people think before writing static methods. That's a good practice when you have heterogeneous teams (the ones where Java is most useful).

Rodrigo Gama
A: 

If foo is private, it may be anything, static or not. But, most of the time it will be not static as these is one less word to type. Then, if you need to use the state because you've changed your code, you can do it right away.

When it is protected or public, it depends on what it does. A rule of thumb is to make it not static when it isn't a part of the instance's behaviour, and make it static when it makes sense to call it without any object. If you are unsure, ask yourself if it makes sense to override the method in a subclass.

Chris
Wow, you sure look at programming differently than I do. I see code as something for the next guy to read--so the more hints you can give them the better. Typing one more or less word is completely irrelevant, and although I'm still considering the original question, having the compiler hint that this method was initially written "statically" and by adding member access you were significantly modifying the usage patters would be much more valuable than being able to "change your code right away".
Bill K
+5  A: 

Interesting question. In practical terms, I don't see the point in making class A's private helper methods static (unless they're related to a publicly-accessible static method in A, of course). You're not gaining anything -- by definition, any method that might need them already has an instance of A at its disposal. And since they're behind-the-scenes helper methods, there's nothing to say you (or another co-worker) won't eventually decide one of those stateless helpers might actually benefit from knowing the state, which could lead to a bit of a refactoring nuisance.

I don't think it's wrong to to end up with a large number of internal static methods, but I don't see what benefit you derive from them, either. I say default to non-static unless you have a good reason not to.

BlairHippo
See, I think that refactoring nuisance would be a GOOD thing. It would force people to take notice that they are dramatically changing the intended implementation. This would be one of the BENEFITS I imagine would come from using the static keyword.
Tom Tresansky
@Tom: Perhaps. I question the value of tying future coders' hands regarding code that exists entirely inside the black box. (Though you're not tying them with particularly strong rope, certainly.) But if the method is static only because that's the default you've adopted and not due to a deliberate choice, what precisely is the intended implementation they'd be noticing?
BlairHippo
How much nuisance would it be to change a private static method to a private instance method? What would you have to do other than remove "static"? OTH If the change was from a static method to a non private instance method, I can see that there may be some headaches.
emory
I'm throwing my hat in the ring with this response, which shows the most thoughtful understanding thus far of the question, and therefore has prompted the most interesting discussion. Barring performance considerations (which I don't think should enter into this discussion, which is really a stylistic one), I'm inclined to agree with BlairHippo- and my own tendencies fall along these lines. I tend not to make methods static unless I conceive of them from the git as such. But I think this may just be one of those cases where you do what feels right, and be consistent about it.
quixoto
@emory: You are correct, the nuisance factor isn't that large. The worst-case scenario I can think of here is if the helper methods talk to each other, meaning you could wind up having to de-static a whole bunch of them. Which would lead to some fairly useless noodling over "Wait a minute -- is this method static for a reason, or is that just Tom defaulting to it again?" My inclination is that if you're going to declare a method static you should have a better reason than "Because I can," but in this case, it's hard to get yourself into much trouble either way.
BlairHippo
+1 The only answer making any sense here. (I was about to add my own.)
Nikita Rybak
A: 

I think letting the methods in Java to be static will result in a rather chaotic implementation by beginner who haven't understand OO correctly. We've been there and think about it. If the methods were static as default how hard it is for us to understand the OO principle?

So yes, once you mastered the concept, it is a bit itchy to have static all over the methods (as result of refactoring). Nothing we ca do about that I think.

NB: Let me guess, are you by any chance have read Clean Code?

nanda
A: 

When you write a static method you should keep in mind that you'r gonna use it at use-site with static-import (make it look class free) and thus it should behave just like a function which doesn't something and may or may not return something and is isolated with the state of class it belongs to. So static methods should be a rare situation.

If you seem to be making a lot of helper methods, then consider using package-private instance methods instead of private ones. Less typing, less boilerplate since you can re-use them as a helper to other classes in the same package.

nabeelalimemon
+4  A: 

I generally don't make them static but probably should. It's valuable as a hint to tell the next coder that this method CANT modify the state of your object, and it's valuable to give you a warning when you modify the method to access a member that you are changing the nature of the method.

Coding is all about communicating with the next coder--don't worry about making the code run, that's trivial. So to maximize communication I'd say that if you really need such a helper, making it static is a great idea. Making it private is critical too unless you are making a Math. like class.

Bill K
+1, exactly my reasaning. If a helper method does not modify any state then it is nice to make this explicit by declaring it static. Most IDEs will also display a static method call different, so it is also clear at the call sites that no state is modified.
Jörn Horstmann
A static method may change the state of an instance by calling methods on the instance. Would be confusing then.
Willi
I agree with what you're saying, but I'm of the opinion that the functions should be package protected... so that you can test them from a separate test class.
RHSeeger
@Willi Schönborn Only if the instance was passed in, which would make it obvious. It's actually a pretty clear, safe assumption that if it is a static method it won't change the state of any object (that isn't passed in). This CAN be violated if you are determined by having a static variable that contains instances--if you do that, document clearly.
Bill K
+2  A: 

It depends i.g. java.lang.Math has no method which isn't static. (You could do a static import to write cos() instead of Math.cos()) This shouldn't be overused but as some code that is intented to be called as a utility it would be acceptable. I.g Thread.currentThread()

stacker
+12  A: 

If a method does not use instance data, then it should be static. If the function is public, this will give the important efficiency boost that you don't need to create a superfluous instance of the object just to call the function. Probably more important is the self-documentation advantage: by declaring the function static, you telegraph to the reader that this function does not use instance data.

I don't understand the sentiment of many posters here that's there's something wrong with having static functions in a Java program. If a function is logically static, make it static. The Java library has many static functions. The Math class is pretty much filled with static functions.

If I need, say, a function to calculate a square root, the rational way to do it would be:

public class MathUtils
{
  public static float squareRoot(float x)
  {
    ... calculate square root of parameter x ...
    return root;
  }
}

Sure, you could make a "more OOPy" version that looked like this:

public class MathUtils
{
  private float x;
  public MathUtils(float x)
  {
    this.x=x;
  }
  public float squareRoot()
  {
    ... calculate square root of this.x ...
    return root;
  }
}

But aside from meeting some abstract goal of using OOP whenever possible, how would this be any better? It takes more lines of code and it's less flexible.

(And yes, I now there's a square root function in the standard Math class. I was just using this as a convenient example.)

If the only place a static function is used and is every likely to be used is from within a certain class, then yes, make it a member of that class. If it makes no sense to call it from outside the class, make it private.

If a static function is logically associated with a class, but might reasonably be called from outside, then make it a public static. Like, Java's parseInt function is in the Integer class because it has to do with integers, so that was a rational place to put it.

On the other hand, it often happens that you're writing a class and you realize that you need some static function, but the function is not really tied to this class. This is just the first time you happened to realize you need it, but it might quite rationally be used by other classes that have nothing to do with what you're doing now. Like, to go back to the square root example, if you had a "Place" class that included latitude and longitude, and you wanted a function to calculate the distance between two places and you needed a square root as part of the calculation, (and pretending there was no square root function available in the standard library), it would make a lot of sense to create a separate square root function rather than embedding this in your larger logic. But it wouldn't really belong in your Place class. This would be a time to create a separate class for "math utilities" or some such.

You ask, "Should foo always be static, regardless of any other considerations?" I'd say "Almost, but not quite."

The only reason I can think of to make it not static would be if a subclass wants to override it.

I can't think of any other reasons, but I wouldn't rule out the possibility. I'm reluctant to say "never ever under any circumstances" because someone can usually come up with some special case.

Jay
+1 for the self-documentation note. Code should convey the programmer's intention, which is why we use things like descriptive names for methods/variables. By declaring a function static, you're making it clear that it doesn't (and should not) rely on internal object state. The fact that it's easier to test is a huge bonus too, imo.
RHSeeger
+1 for being right.
Erick Robertson
Yeah but the problem here is that Math deals with primitives. If it didn't then there would be no need for statics (see the BigNumber classes for reference). So the need for statics in this particular case is just a side effect of the core issue that Java should not have had primitives in the first place.
CurtainDog
Why should Java not have had primitives in the first place? It's much more efficient to use a primitive than an object. Even if I'm dealing with objects, I may want to use statics if I cannot extend the "subject" class because it is final. Or if I need to operate on objects that I am not creating and so cannot make in the desired subtype, like if it is the return value from a class that I didn't write. Also, a function may be speicalized to my problem, so that putting it in, say, a subclass of String or Integer is more confusing than clarifying.
Jay
+2  A: 

Java conflates the concepts of module, namespace, adt, and class, as such to claim that some class-oriented OO-purity should prevent you from using a java class as a module, namespace, or adt is ridiculous.

Yes the methods should be static. Purely internal support methods should be private; helper methods protected; and utility functions should be public. Also, there is a world of difference between a static field, a static constant, and a public static method. The first is just another word for 'global variable'; and is almost always to be avoided, even mediation by accessor methods barely limits the damage. The second is treating the java class as a namespace for a symbolic constant, perfectly acceptable. The third is treating the java class as a module for a function, as a general rule side-effects should be avoided, or if necessary, limited to any parameters passed to the function. The use of static will help ensure that you don't inadvertently break this by accessing the object's members.

The other situation you will find static methods invaluable is when you are writing functional code in java. At this point most of the rules-of-thumb developed by OO-proponents go out the window. You will find yourself with classes full of static methods, and public static function constants bound to anonymous inner functors.

Ultimately java has very weak scoping constructs, conflating numerous concepts under the same 'class' and 'interface' syntax. You shouldn't so much 'default' to static, as feel free to use the facilities java offers to provide namespaces, ADT's, modules, etc as and when you feel the need for them.

Recurse
A: 

I think "private static" (edit: for methods) is kind of an oxymoron in Java. The main point of static methods in my mind is to provide access to functions outside of the context of object instances. In other words, they're practically only ever useful if they're public. If you're only calling a method from within the context of a single object instance, and that method is private, it makes no sense to make it static. (edit: but, it makes no practical difference).

In this sort of case, I usually try to make the methods abstract enough that they're useful in other contexts, and I make them public in a utility class. Look at it as writing supporting library code, and think hard about your api.

Jesse
+2  A: 

A static method is used to identify a method (or variable for that matter) that does not have to do with the objects created from that class but the class itself. For instance, you need a variable to count the number of objects created. You would put something like: 'private static int instances = 0;' and then put something in the constructor for that class that increments 'instances' so you may keep count of it.

Glenn Nelson
No, static methods are not "methods for the class". They are simply methods that do not depend or modify instance state.
Bruno Reis
@Bruno Wrong. Glenn is exactly right. A static method (or "class methods") belongs to the class it is defined in (recommend reading http://download-llnw.oracle.com/javase/tutorial/java/javaOO/classvars.html ). The effect that you can't access any instance state is the result from that the method does not belong to that instance! +1
Arne
+1  A: 

Do think hard before creating a static method, but there are times when they are a good solution.

Joshua Bloch in "Item 1: Consider Static Factory Methods Instead of Constructors" in Effective Java makes a very persuasive case that static methods can be very beneficial. He gives the java.util.Collections class's 32 static factory methods as an example.

In one case, I have a hierarchy of POJO classes whose instances can be automatically serialized into XML and JSON, then deserialized back into objects. I have static methods that use Java generics to do deserialization: fromXML(String xml) and fromJSON(String json). The type of POJO they return isn't known a priori, but is determined by the XML or JSON text. (I originally packaged these methods into a helper class, but it was semantically cleaner to move these static methods into the root POJO class.)

A couple of other examples:

  • Using a class as a namespace to group related methods (eg, java.lang.Math).
  • The method truly is a private class-specific helper method with no need to access instance variables (the case cited here). Just don't sneak a this-equivalent into its argument list!

But don't use statics unthinkingly or you run the danger of falling into a more disorganized and more procedural style of programming.

Jim Ferrans
+24  A: 

To answer the question on the title, in general, Java methods should not be static by default. Java is an object-oriented language.

However, what you talk about is a bit different. You talk specifically of helper methods.

In the case of helper methods that just take values as parameters and return a value, without accessing state, they should be static. Private and static. Let me emphasize it:

Helper methods that do not access state should be static.


1. Major advantage: the code is more expressive.

Making those methods static has at least a major advantage: you make it totally explicit in the code that the method does not need to know any instance state.

The code speaks for itself. Things become more obvious for other people that will read your code, and even for you in some point in the future.

2. Another advantage: the code can be simpler to reason about.

If you make sure the method does not depend on external or global state, then it is a pure function, ie, a function in the mathematical sense: for the same input, you can be certain to obtain always the same output.

3. Optimization advantages

If the method is static and is a pure function, then in some cases it could be memoized to obtain some performance gains (in change of using more memory).

4. Bytecode-level differences

At the bytecode level, if you declare the helper method as an instance method or as a static method, you obtain two completely different things.

To help make this section easier to understand, let's use an example:

public class App {
    public static void main(String[] args) {
        WithoutStaticMethods without = new WithoutStaticMethods();
        without.setValue(1);
        without.calculate();

        WithStaticMethods with = new WithStaticMethods();
        with.setValue(1);
        with.calculate();
    }
}

class WithoutStaticMethods {

    private int value;

    private int helper(int a, int b) {
        return a * b + 1;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public int calculate() {
        return helper(value, 2 * value);
    }
}

class WithStaticMethods {

    private int value;

    private static int helper(int a, int b) {
        return a * b + 1;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public int calculate() {
        return helper(value, 2 * value);
    }
}

The lines we are interested in are the calls to helper(...) on the classes WithoutStaticMethods and WithStaticMethods.

Without static methods

In the first case, without static methods, when you call the helper method the JVM needs to push the reference to the instance to pass it to invokespecial. Take a look at the code of the calculate() method:

 0 aload_0
 1 aload_0
 2 getfield #2 <app/WithoutStaticMethods.value>
 5 iconst_2
 6 aload_0
 7 getfield #2 <app/WithoutStaticMethods.value>
10 imul
11 invokespecial #3 <app/WithoutStaticMethods.helper>
14 ireturn

The instruction at 0 (or 1), aload_0, will load the reference to the instance on the stack, and it will be consumed later by invokespecial. This instruction will put that value as the first parameter of the helper(...) function, and it is never used, as we can see here:

0 iload_1
1 iload_2
2 imul
3 iconst_1
4 iadd
5 ireturn

See there's no iload_0? It has been loaded unnecessarily.

With static methods

Now, if you declare the helper method, static, then the calculate() method will look like:

 0 aload_0
 1 getfield #2 <app/WithStaticMethods.value>
 4 iconst_2
 5 aload_0
 6 getfield #2 <app/WithStaticMethods.value>
 9 imul
10 invokestatic #3 <app/WithStaticMethods.helper>
13 ireturn

The differences are:

  • there's one less aload_0 instruction
  • the helper method is now called with invokestatic

Well, the code of the helper function is also a little bit different: there's no this as the first parameter, so the parameters are actually at positions 0 and 1, as we can see here:

0 iload_0
1 iload_1
2 imul
3 iconst_1
4 iadd
5 ireturn

Conclusion

From the code design angle, it makes much more sense to declare the helper method static: the code speaks for itself, it contains more useful information. It states that it does not need instance state to work.

At the bytecode level, it is much more clear what is happening, and there's no useless code (that, although I believe the JIT has no way to optimize it, would not incur a significant performance cost).

Bruno Reis
There might be an answer in here somewhere, but it's obfuscated by all the byte code.
Erick Robertson
If I could give a +2, you'd have it. That's one of the best answers I've seen this month. (Thanks!)
Dean J
Your point about the CPU cycles wasted passing the "this" reference is true, indeed I started to say something about that in my own answer, but then I dropped it as trivial. I suppose if you're calling the function a million times the extra CPU cycles could add up. I'm not saying you're wrong, just that in the scheme of things this is a minor point.
Jay
PS I still gave you a +1 on your answer because I think the rest of it is dead on.
Jay
I don't buy 1 and 2. The static modifier does NOT make sure that there is no instance state that is modified by it. There might be reference parameters or a static field that hold references to instances of the class. You have to look at the code anyway, you can't be sure that there is no state modified, you can't be sure that there are no side effects, you can't be sure that it is a function in the mathematical sense. -1
Arne
-1 The headings are too 'shouty'. And your byte code analysis, while your effort is really great, I think argues more strongly for the case that there's no real technical reason for using static.
CurtainDog
@Arne: if you want to take things to the extreme, you can't for instance assume that in Java a "private final" field is really constant (ie, it can be modified by reflection, as per section 17.5.3 of the Java Specs). By following your reasoning (when you 'don't buy' my 2nd point), one should read the whole source code of a huge project just to be sure that a "private final" field isn't really modified anywhere (oh, and the IDE or "Edit->Find" wouldn't be helpful here, since one can access the field by dynamically building its name). Man, you talk about hacking, not software engineering.
Bruno Reis
@CurtainDog: on the sense of software engineering, points 1 and 2 are really strong (major?) technical reasons. I'm sorry if you can't understand their importance, but I don't think I can make it more clear.
Bruno Reis
@Bruno: Using an static field from a staic method is all ... but not a hack! It's nothing unusual to access a static member from a static method. You say: place a static on the method and this makes sure the method does not modify state. And this is plainly wrong.
Arne
@Arne: I think you're playing word games here. By definition, a static method cannot update the state of its associated "this" instance, because it has no associated "this" instance. Sure, it can update an instance of some other object to which it has access. It could update public instances of other classes. It could send messages over the Internet to update instances of classes in other systems. That's not the question.
Jay
@Jay: The point is, that bruno suggests to use static to ensure that the typed method is a pure function without side effects. And static can not garantee this.
Arne
@Arne: Well, he does include the caveat, "If you make sure the method does not depend on external or global state ..." (Or did he add that with a later edit?) Does declaring static guarantee that a function is literally stateless? No. To the extent that you're point is that it's not a guarantee, true, I agree. But it does limit the dependencies. It's a step in the right direction.
Jay
@Arne: the point is, if you use Java, you must know that everything is possible. The language does not give you guarantees. Private fields can usually be accessed/modified externally, final fields can be modified after initialization, etc. This makes software engineering a hell. This can be fun if you want to hack some code, but for serious development, this can be a problem. Unless you make some conventions: "I promise not to use reflection to modify private final fields after initializaion, I promise not to access/modify private state". The language won't enforce anything. If you want it,
Bruno Reis
then Java is not the language for you. You could try some Haskell, for example. But if you want to use Java, you two options: either you define (and follow) a set of natural and commonly used and widely accepted conventions (such as declaring methods that do not depend on instance state as static) that makes reading and understanding the code much easier, or you won't be doing software engineering, you will be just hacking some unintelligible code. If you still don't see my point, it is: you should aim for clarity, and use every resource available to you to make your code easier to understand.
Bruno Reis
I can see your point. But I don't share your opinion. What I see is, that you get very few from making private methods static (and it does not help if you declare this a "widly accepted convention", which it isn't, or calling others "hacking" while YOU do engeneering). You make the code only more expressive for developers that use static the same way you do (an annotation or comment "stateless" would do nearly the same) and the reasoning about the code is not much improved because of many other possible side effects. The abuse of class methods as instance methods is a mistake (imho).
Arne
@BR - The rational behind this behaviour is well explained here: http://stackoverflow.com/questions/3300680/does-reflection-breaks-the-idea-of-private-methods-because-private-methods-can-b/3304350#3304350
CurtainDog
Copied straight from google's performance guide on how to program for android:Prefer Static Over Virtual"If you don't need to access an object's fields, make your method static. Invocations will be about 15%-20% faster. It's also good practice, because you can tell from the method signature that calling the method can't alter the object's state."Source: http://developer.android.com/guide/practices/design/performance.html#prefer_static
Nailer
+3  A: 

I find it difficult to subscribe to those avoid-static-methods theories. They are there to promote a completely sanitary object-oriented model anti-septically cleansed of any deviation from object relationships. I don't see any way essential to be anti-septically pure in the practice object-orientedness.

Anyway, all of java.util.Arrays class are static. Numeric classes Integer, Boolean, String have static methods. Lots of static methods. All the static methods in those classes either convert to or from their respective class instances.

Since good old Gosling, et al, proved to be such useful role models of having static methods - there is no point avoiding them. I realise there are people who are perplexed enough to vote down my response. There are reasons and habits why many programmers love to convert as much of their members to static.

I once worked in an establishment where the project leader wanted us to make methods static as much as possible and finalize them. On the other hand, I am not that extreme. Like relational database schema design, it all depends on your data modelling strategy.

There should be a consistent reason why methods are made static. It does not hurt to follow the standard Java library pattern of when methods are made static.

The utmost importance is programming productivity and quality. In an adaptive and agile development environment, it is not only adapting the granularity of the project to respond effectively to requirements variation, but also adapting programming atmosphere like providing a conformable coding model to make best use of the programming skill set you have. At the end of the day (a project almost never ends), you want team members to be efficient and effective, not whether they avoided static methods or not.

Therefore, devise a programming model, whether you want MVP, injection, aspect-driven, level of static-avoidance/affinity, etc and know why you want them - not because some theoretical nut told you that your programming practice would violate oo principles. Remember, if you work in an industry it's always quality and profitability not theoretical purity.

Finally what is object-oriented? Object-orientation and data normalization are strategies to create an orthogonal information perspective. For example, in earlier days, IBM manuals were written to be very orthogonal. That is, if a piece of info is written somewhere in a page within those thousands of manuals, they avoid repeating that info. That is bad because you would be reading learning how to perform a certain task and frequently encounter concepts mentioned in other manuals and you would have to be familiar with the "data model" of the manuals to hunt those connecting pieces of info thro the thousands of manuals.

For the same reason, OS/2 failed to compete with Microsoft because IBM's concept of orthogonality was purely machine and data based and IBM was so proudly declaring their true object-orientedness vs Microsoft's false object-orientedness pandering to human perspective. They had forgotten we humans have our own respective varying orthogonal perspectives of information that do not conform to data and machine based orthogonality or even to each other.

If you are familiar with the topology of trees, you would realise that you could pick any leaf node and make it the root. Or even any node, if you don't mind having a multi-trunk tree. Everyone thinks his/her node is the root when in fact any could be the root. If you think your perspective of object-orientation is the canon, think again. More important is to minimise the number of nodes that are accepted as candidate roots.

There needs to be a compromise between effectiveness and efficiency. There is no point in having an efficient data or object model that can be hardly effectively used by fellow programmers.

Blessed Geek
The problem with your examples is that they are inextricably linked to primitives, were Java more OO the need for these static methods would evaporate.
CurtainDog
+3  A: 

Unless you pass in an object reference, a static method on an class enforces that the method itself cannot mutate the object because it lacks access to this. In that regard, the static modifier provides information to the programmer about the intention of the method, that of being side-effect free.

The anti-static purists may wish to remove those into a utility class which the anti-utility purists surely object to. But in reality, what does artificially moving those methods away from their only call site achieve, other than tight coupling to the new utility class.

A problem with blindly extracting common utility methods into their own classes is those utilities should really be treated as a new public API, even if it's only consumed by the original code. Few developers, when performing the refactoring, fail to consider this. Fast-forward to other devs using the crappy utility class. Later on somebody makes changes to the extension to suit themselves. If you're lucky a test or two breaks, but probably not.

Robert Paulson
+3  A: 

I usually

Perform these steps in order, as needed:

a) I write some code in a member method, figure out that I can probably re-use some of this code and

Extract to non-static method

b) Now I'll see if this method needs access to state or if I can fit its needs into one or two parameters and a return statement. If the latter is the case:

Make method (private) static

c) If I then find that I can use this code in other classes of the same package I'll

Make method public and move Method to a package helper class with default visibility

E.g. In package com.mycompany.foo.bar.phleeem I would create be a class PhleeemHelper or PhleeemUtils with default visibility.

d) If I then realize that I need this functionality all over my application, I

Move the helper class to a dedicated utility package

e.g. com.mycompany.foo.utils.PhleeemUtils

Generally I like the concept of least possible visibility. Those who don't need my method shouldn't see it. That's why I start with private access, move to package access and only make things public when they are in a dedicated package.

seanizer
A: 

Plenty of interesting answers.

If you desperately seek a rule, then use this:

If the code is only ever used by instance methods of a single class, then make it an instance method - it is simply an extraction of code out of an instance context - which could be refactored back into (or out of) methods that access instance state.

If the code is used by MORE THAN ONE class, and contains no access to instance variables in the class in which the method resides, then make it static.

End of story.

xagyg
+1  A: 

No, the use of statics should be quite niche.

In this case the OP is likely 'hiding' state in the parameters passed into the static method. The way the question is posed makes this non-obvious (foo() has no inputs or outputs), but I think in real world examples the things that should actually be part of the object's state would fall out quite quickly.

At the end of the day every call to obj.method(param) resolves to method(obj, param), but this goes on at a way lower level than we should be designing at.

CurtainDog
A: 

Most static methods are written because

  1. You break down a complex method into submethods, or
  2. You wish String (or Date, or...) had some functionality that it doesn't have

The first is not bad per se, but it's often a sign that you're missing objects. Instead of working with default types such as String or List, try inventing your own classes and move the static methods to those classes.

The second reason produces the always-popular StringUtil, DateUtil, FooUtil classes. These are problematic because you have no way to discover that they exist, so programmers often write duplicates of these utility methods. The solution, again, is to avoid using String and Date all the time. Start creating your own objects, perhaps by wrapping the original object. The static methods become non-static methods of the new object.

xpmatteo