This is a fairly fundamental question that has bugged me ever since I started learning Java (which admittedly was not that long ago). Imagine you have a method that takes a variable, performs a basic mathematical function on that variable, then returns the result. There are two main ways I can access this method:
1. Make the method static. Access the method directly with something like:
2. Make the method non static. Access the method via an instance of that class, something like:
Under which circumstances (broadly speaking) would you choose one over the other? Is one fundamentally better? The first way (using static methods) always seems much easier to me, but it seems whenever I read java tutorials, it encourages using class instances more.
Obviously this is one of those questions where the answer could contain a lot of 'it depends' but if someone could point me in the right direction, or link me to an article that explains it in depth, it would be much appreciated. Google searching has led me to a lot of articles explaining the difference between a static and instance methods, but very little on why you should use one over the other.
Ian Taylor wrote:...Under which circumstances (broadly speaking) would you choose one over the other?
Broadly speaking, if the method defines a self-contained "function", then it's better to make it static (and possibly even define it in a utility class); if it relies on any state of a particular object, then it should almost invariably be an instance method.
So, a logarithm function should probably be static, since what it does doesn't rely on anything except its parameters; but a currentSpeed() method for a Car is linked to a specific Car, and therefore should be an instance method. The alternative of making it a static method that takes a Car as a parameter makes the method overly reliant on the way a Car produces that information, and so breaks encapsulation (Google it) and makes the method tightly coupled - one of those "code smells" that you may have already heard about, and that we hoary old farts hate.
Is one fundamentally better? The first way (using static methods) always seems much easier to me, but it seems whenever I read java tutorials, it encourages using class instances more.
I'd say that, as a guideline, they're probably right. Instance methods are less "invasive" to a design, so you should generally prefer them to a static method if you have a choice. As with everything of course, there are exceptions; but I'd say that a good rule of thumb would go something like this:
Prefer instance methods to static ones, and only write the latter if you feel confident that you can justify it.
Whatever you do, don't write static methods simply because you find them easier - it's sloppy thinking and, as you get more experienced, it won't always be the case.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
For that particular case--a pure function with no side effects--a static method may be appropriate, as it doesn't depend on or alter the state of any object. In fact, the core API has methods very similar to that: Math.sin(), Math.cos(), Math.log(), etc. Additionally, when we define our own libraries for use in multiple projects, there will sometimes be "helper" classes that have only static methods--stuff like manipulating Strings or checking if they're empty, calling close() with proper try/catch around it, etc.
Cases where you would create an instance and operate on it, in contrast, include those where you're not just performing independent functions for their results, but are giving an object state, modifying that state, querying that state, and asking it to keep that state between method calls. These will often represent physical objects or specific "noun" abstractions in our business domain--Student, Employee, Account, Message, etc.
That distinction is what's most often cited as the litmus test for static vs. non-static methods, but there's another case that's equally important: polymorphism.
In Java, static methods are not runtime polymorphic. They cannot be overridden. This means we can't just declare a reference type at compile time, and then get different behaviors at runtime depending on the different requirements for different uses.
For example, going back to our utility class full of mathematical operations. Let's say there are some operations where it might be advantageous to use one approach to calculating the result in some situations, and a different approach in other situations. We might wish to do something like this:
Depending on something we don't know at compile time, we get different implementations of the method, where each one is optimized for its particular set of conditions. We can't do this with static methods. This kind of polymorphism requires instances. (In Java at least. Some languages support runtime polymorphism of static methods.)
If you search this forum, you come across some very dubious classifications of methods, and that was the most dubious of the lot. You will find a sin(x) function comes out as 1368, so that is a candidate for being made static.
As you get more experienced, you will come across factory methods; those are usually static because you might have to call them before any instances of the class exist.
Methods in interfaces and abstract methods are never static.
Joel Salatin has signs on his property that say "Trespassers will be Impressed!" Impressive tiny ad: