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 cou
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.
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.
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.
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).
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.
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.