I\'ve recently been looking through my warnings in Eclipse and come across this one:
1. Declaring method static
gives slight performance benefit, but what is more useful, it allows using it without having an object instance at hand (think of for example about factory method or getting a singleton). It also serves the documentational purpose of telling the nature of the method. This documentational purpose should not be ignored, as it gives immediate hint about the nature of the method to the readers of the code and users of the API and also serves as a tool of thinking for the original programmer - being explicit about the intended meaning helps you also think straight and produce better quality code (I think based on my personal experience, but people are different). For example, it is logical and hence desirable to distinguish between methods operating on a type and methods acting on an instance of the type (as pointed out by Jon Skeet in his comment to a C# question).
Yet another use case for static
methods is to mimic procedural programming interface. Think of java.lang.System.println() class and the methods and attributes therein. The class java.lang.System
is used like a grouping name space rather than an instantiable object.
2. How can Eclipse (or any other programmed or other kind of - biocomposable or non-biocomposable - entity) know for sure which method could be declared as static? Even if a base class is not accessing instance variables or calling non-static methods, by the mechanism of inheritance the things can change. Only if the method cannot be overridden by inheriting subclass, can we claim with 100% certainty that the method really can be declared static
. Overriding a method is impossible exactly in the two cases of being
private
(no subclass can use it directly and does not even in principle know about it), orfinal
(even if accessible by the subclass, there is no way to change the method to refer to instance data or functions).Hence the logic of the Eclipse option.
3. The original poster also asks: "Pointing out a method as static, I suppose is showing that you don't use any instance variables therefore could be moved to a utils style class?" This is a very good point. Sometimes this kind of design change is indicated by the warning.
It is very useful an option, which I would personally make sure to enable, were I to use Eclipse and were I to program in Java.
Whenever you write a method, you fulfill a contract in a given scope. The narrower the scope is, the smaller the chance is that you write a bug.
When a method is static, you can't access non-static members; hence, your scope is narrower. So, if you don't need and will never need (even in subclasses) non-static members to fulfill your contract, why give access to these fields to your method? Declaring the method static
in this case will let the compiler check that you don't use members that you do not intend to use.
And moreover, it will help people reading your code understand the nature of the contract.
That's why it's considered good to declare a method static
when it's actually implementing a static contract.
In some cases, your method only means something relative to an instance of your class, and it happens that its implementation doesn't actually use any non-static field or instance. In such cases, you would not mark the method static
.
Examples of where you would not use the static
keyword:
There is no concept with optimization here.
A static
method is static
because you explicitly declare that method doesn't rely on any instance the enclosing class just because it doesn't need to. So that Eclipse warning, as stated in documentation:
When enabled, the compiler will issue an error or a warning for methods which are private or final and which refer only to static members.
If you don't need any instance variable and your method is private (can't be called from outside) or final (can't be overriden) then there is no reason to let it be a normal method instead that a static one. A static method is inherently safer even just because you are allowed to do less things with it (it doesn't need any instance, you don't have any implicit this
object).
I've no info on the performance, I suppose it is marginally better at most, since the code does not need to do dynamic dispatch based on the type.
However, a much stronger argument against refactoring into static methods is that currently using static is considered bad practice. Static methods / variables do not integrate well into an object oriented language and also, hard to test properly. This is the reason why some newer languages forego the concept of static methods/variables altogether, or try to internalize it into the language in a way that plays better with OO (eg Objects in Scala).
Most of the time, you need static methods to implement functions that are only using parameters as an input and producing an output using that (eg utility/helper functions) In modern languages, there is a first class Function concept that allows that, so static is not needed. Java 8 will have lambda expressions integrated, so we are moving into this direction already.
See Samuel's answer on how the scope of the method changes. I guess, this is the main aspect of making a method static.
You also asked about performance:
There might be a tiny performance gain, because a call to a static method does not need the implicit "this" reference as parameter.
However, this performance impact is really tiny. Therefore, it's all about the scope.
From the Android Performance guidelines:
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.
http://developer.android.com/training/articles/perf-tips.html#PreferStatic