In my application there are many classes which contain methods for processing data which can be computation and data enrichment.
My question is - if the class doesn't have any class level variables, can I make all the methods in the class static?
I suppose that there won't be any issues with threading.
Are there any consequences? Are there any performance advantage as I don't have to instantiate the class?
A sample class:
Class A{
public Object findTheCar(String id){
Car car= new Car();
//do something
return car;
}
}
I intend to change the above to static.
One rule-of-thumb: ask yourself "does it make sense to call this method, even if no Obj has been constructed yet?" If so, it should definitely be static.
So in a class Car
you might have a method double convertMpgToKpl(double mpg)
which would be static, because one might want to know what 35mpg converts to, even if nobody has ever built a Car. But void setMileage(double mpg)
(which sets the efficiency of one particular Car) can't be static since it's inconceivable to call the method before any Car has been constructed.
(Btw, the converse isn't always true: you might sometimes have a method which involves two Car objects, and still want it to be static. E.g. Car theMoreEfficientOf( Car c1, Car c2 )
. Although this could be converted to a non-static version, some would argue that since there isn't a "privileged" choice of which Car is more important, you shouldn't force a caller to choose one Car as the object you'll invoke the method on. This situation accounts for a fairly small fraction of all static methods, though.)
Though there are some valid reasons to use static methods:
Performance: if you want some code to be run, and don't want to instantiate an extra object to do so, shove it into a static method. The JVM also can optimize static methods a lot (I think I've once read James Gosling declaring that you don't need custom instructions in the JVM, since static methods will be just as fast, but couldn't find the source - thus it could be completely false). Yes, it is micro-optimization, and probably unneeded. And we programmers never do unneeded things just because they are cool, right?
Practicality: instead of calling new Util().method(arg), call Util.method(arg), or method(arg) with static imports. Easier, shorter.
Adding methods: you really wanted the class String to have a removeSpecialChars() instance method, but it's not there (and it shouldn't, since your project's special characters may be different from the other project's), and you can't add it (since Java is minimally sane), so you create an utility class, and call removeSpecialChars(s) instead of s.removeSpecialChars(). Sweet.
Purity: taking some precautions, your static method will be a pure function, that is, the only thing it depends on is its parameters. Data in, data out. This is easier to read and debug, since you don't have inheritance quirks to worry about. You can do it with instance methods too, but the compiler will help you a little more with static methods (by not allowing references to instance attributes, overriding methods, etc.).
You'll also have to create a static method if you want to make a singleton, but... don't. I mean, think twice.
Now, more importantly, why you wouldn't want to create a static method? Basically, polymorphism goes out of the window. You'll not be able to override the method, nor declare it in an interface. It takes a lot of flexibility out from your design. Also, if you need state, you'll end up with lots of concurrency bugs and/or bottlenecks if you are not careful.
So define static methods in the following scenarios only:
- If you are writing utility classes and they are not supposed to be changed.
- If the method is not using any instance variable.
- If any operation is not dependent on instance creation.
- If there is some code that can easily be shared by all the instance methods, extract that code into a static method.
- If you are sure that the definition of the method will never be changed or overridden. As static methods can not be overridden.
Lets also discuss it in more details:
Advantages:
Static members/methods are used as in helper classes say like Math or in constants classes. which helps other objects to utilize Strings or useful functions for which you do not need to create object but invoked using Class name. Example – singleton objects are invoked using a static function.
Disadvantages:
Static members are part of class and thus remain in memory till application terminates and can’t be ever garbage collected. Using excess of static members sometime predicts that you fail to design your product and trying to cop of with static / procedural programming. It denotes that object oriented design is compromised. This can result in memory over flow. Also there are certain disadvantages if you make any method static in Java for example you can not override any static method in Java so it makes testing harder you can not replace that method with mock. Since static method maintains global state they can create subtle bug in concurrent environment which is hard to detect and fix.
Things to remember:
The static variable will be part of the class definition rather than on the heap. However static variables are useful when you know there will be accesses to the object from multiple places. Access to static resources is not thread safe. You might get weird/unpredictable results in a threaded environment. But if your only reading the static value then using threads for it is fine.
How Static Breaks encapsulation:
The technical implementation of them is to allow state to be maintained across all instances of a class. The problem is that this is intrinsically not OOP because it disregards encapsulation. If a variable can be altered by any instance of a class then the fundamental principle behind encapsulation/information hiding is lost entirely: An object is no longer in complete control of its state. Its state now relies on variables which are essentially global. Which we know is bad. Even private static variables maintain state at a global level but simply limit its access. Any instance of the object can alter the static variable which causes ambiguity as individual instances of the object no longer have control over their own state. State changes can arbitrarily happen without knowledge of an object which relies on that state which is problematic because the object may not work correctly when this happens. Much as it’s often said that “Inheritance breaks encapsulation” statics do this in a far more severe way: By not just exposing internal implementation but also by exposing internal state.
In Your Example Question:
As you mentioned, the method is going to be used in multithreaded invironment, think of the below problem (modified your code):
public Object findTheCar(String id) {
Car car = null; //Line 2
if (id != null) {
car = new Car();
}
//Line 6
// do something
//
//Line 10
return car;
}
In the above: if this executed from two threads, and 1st thread is at
line 6, and second thread is at line 2, still this will be thread
safe.
Because:
Local variables are stored in each thread's own stack. That means that local variables are never shared between threads. That also means that all local primitive variables are thread safe.
Local references to objects are a bit different. The reference itself is not shared. The object referenced however, is not stored in each threads's local stack. All objects are stored in the shared heap. If an object created locally never escapes the method it was created in, it is thread safe. In fact you can also pass it on to other methods and objects as long as none of these methods or objects make the passed object available to other threads.
Object members are stored on the heap along with the object. Therefore, if two threads call a method on the same object instance and this method updates object members, the method is not thread safe.
Thread safety check: If a resource is created, used and disposed within the control of the same thread, and never escapes the control of this thread,the use of that resource is thread safe.
From: http://tutorials.jenkov.com/java-concurrency/thread-safety.html
If you have no class level variables, then yes, you can make all the methods on your class static. And it might even be slightly more efficient due to avoiding object instantiations. But in object oriented programming, objects have "state" and "behavior". Your objects have no state, only behavior. So are you really doing object oriented programming here? I would argue you are not (which isn't necessarily a bad thing). But maybe you might be more comfortable in a non-OO programming language.
Class without properties is thread safe. So you can work with class instance or make static method. Both will work fine. This is the question of your application architecture. If this simple Java application, I would use static method here.
There are two issues that I think what most other answers completely ignored so far.
First of all, static is an anomaly in objected oriented programming. If you look at it, it is simply "procedural programming" in disguise. This could mean: if your code consists mainly of static methods that somehow massage certain data ... chances are: you didn't do a good job in proper OO modeling/design. Because, when you create OO designs, you look into creating abstractions; and bringing together "data and behavior" using reasonable encapsulation; and even more important by providing clever information hiding.
Then (almost as worse in my eyes): using static puts a huge burden on the testability of your code. So, chances are: you are either not doing TDD/unit tests; or you already resorted to byte-code-manipulating frameworks such as PowerMock in order to test code that uses static methods. And both of those options are rather ... not so good.
So, long story short: The answer from shridutt gives you a good starting point to assess what could be static. But I wholeheartedly recommend you to first step back, and for example: show some of your code to experienced designers/coders and get their feedback regarding "how OO and testable is this stuff".
Your question sounds like you could benefit more from thinking a bit more about your code than from adding some "static"s here or there.
It depends on need,if we want to make methods static or not. A good thumb rule is if the method is going to called (used) across the application for performing some standard operations it is usually ok to consider making them static.
Drawback of overusing static is related to disposing and releasing object since, static method will stay in memory till program is stopped (re-started), overuse of static can have some impact on memory consumption.
You can definitely make all the methods static. Why not? If the language allows it, and it makes sense to you, do it. I've rarely benefited from doing something that didn't make sense to me just because I'd not seen that done before or because it didn't follow some design pattern (like "OO"—that means a lot of things to many people, and Java—especially Java 8—actually supports many paradigms in addition to OO). I definitely wouldn't add lines of code that aren't necessary (Obj a = new Obj(); a.do()
vs Obj.do()
).
In terms of prior art, such classes are often called "utility classes". But there's nothing that has to be utility about such a class. Personally, I use static methods when I see no need to capture values or references within a class instance. There are many times this arises for me, and I've seen this all over in other people's programming as well.
If the methods do not modify a particular instance, that is, if the method does not change the instance variables of the object then you can make the method static.If you're making all the methods static, then all the variables outside methods should be static as well.
About threading, as per my knowledge, the difference would be when you would want to synchronize your code.For instance methods, you synchronize or you lock on objects, however for static methods you synchronize on class variables.So at a particular time in your class, only one synchronized block will be executing.
(For instance methods, for n instances, n synchronized blocks could execute).
For performance
In case of static methods,the binding is at compile time and for instance methods the binding is dynamic, that is at run time.Also the compiler implicitly inserts a this for instance methods.So static methods are slighly faster than instance methods.
In inheritance, static methods cannot be overriden, but then you can always call the method directly with the class, so that's no issue.
So, if you're not instantiating the class, making the methods static and using it as a helper class is a good idea.