Related
I know what static is, but just not sure when to use it.
static variable:
I only used it for constant fields. Sometimes there are tens of constants in a class, so using static constants can save lots of memory. Is there any other typical use cases?
static method:
I use it when I make a class about algorithms. For example, a class which provides different sorting algorithms. Is it against OOP design? I think it is better to maintain this way rather than implementing sorting algorithms inside each class that needs to use them. Am I wrong? What are some good use cases?
Also, are there any performance difference between using static and non-static fields/methods?
You are describing cases where you've used static, but this doesn't quite explain fundamentally why you would use static vs non-static - they are more than just keywords for constants and utility methods.
When something is not static (instance), it means that there is an instance of it for each instance of the class. Each one can change independently.
When something is static, it means there is only one copy of it for all instances of the class, so changing it from any location affects all others.
Static variables/methods typically use less memory because there is only one copy of them, regardless of how many instances of the class you have. Statics, when used appropriately, are perfectly fine in object oriented design.
If you have a method/variable that you only need one instance of (e.g. a constant or a utility method), then just make it static. Understand though that making a method static means it cannot be overridden. So if you have a method you want to override in a subclass, then don't make it static.
The general rule of thumb is - if you need only one copy of it, make it static. If you need a copy per instance, then make it non static.
Is there any other typical use cases?
Global Variables
Is it against OOP design?
Not exaclty, the point is that static methods are stateless since you don't need a particular instance of a class. My favorite approach is for utility methods (like Apache Commons). But you may be aware that some methods may be better placed as class members instead of static.
Also static methods can make class testability harder once you can't override these methods or replace by mock implementation.
Performance difference ?
There's a performance Android recommendation from Google that says "prefer static over virtual":
http://developer.android.com/training/articles/perf-tips.html#PreferStatic
I'm not sure it's true for JVM since Android uses a different VM, but it makes sense given the reasons the link points out:
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."
My personal rule of thumb is that static things are "just hanging out there". They are things that (disclaimer, not entirely true) are global, but make sense to include with this one particular class.
Static fields are good if you find yourself loading some heavyweight objects repeatedly. For instance, the project I'm working on now has a toggle between two images. These are static fields that are loaded with the application and kept in memory, rather than reloading them every time and letting GC take care of the mess.
Apart from very specific situations, I use static (and final) variables for constants only. It's a totally valid to use them, of course.
I tend to avoid static utility methods, because they make it harder to write unit tests for the code (mocking the results of the method invocation). When you start developing Test Driven way, this issue becomes quite apparent. I prefer using dependency injection and singleton beans (though it depends on your needs and situation).
Static variables belong to a class, hence shared by all the objects, so memory usage is less if you really want the varible to be shared. If you declare the variable as public and static, then it is globally available for everyone.
Static methods are generally the utility methods, depending on the access modifier, those can be used within a class or across the classes. Static utility class will help to reduce the memory usage again because you need not to create the object to call those methods.
The static field has one value among all objects and they call it Class member also because it's related to the class.
You can use static filed as a utility.
an example just Assume we need to know how many instances we have :
class Counter
public class Counter {
public static int instanceCount ;
public Counter()
{
instanceCount++;
}
public int getInstanceCount()
{
return instanceCount;
}
}
After creating two instances of Counter Class. But they share the same instanceCount field because it's a static field so the value of instanceCount will become the same in firstCounter and secondCounter .
Class main
Counter firstCounter = new Counter();
// will print 1
System.out.println(co.getInstanceCount());
// will print 2
Counter secondCounter = new Counter();
System.out.println(co1.getInstanceCount());
That's pretty self-explanatory. In Java, (and all OO languages I suppose) should I declare instance method when it's the only choice or generally we don't care about it?
Methods are static when you dont need them to know about class state to process something. Helper methods are good examples of this scenario.
DateUtils.getDateNowInGMT()
The method above does not need any state to give you an answer. The one below does.
Withdrawer w = new Withdrawer.Builder().account(12545).build();
w.withdraw(100);
You cannot withdraw() money without knowing the account number, which is state associated with the Withdrawer. You could argue of course that this could be a static method and passing account information to the method would solve the problem, but it would make it inconvenient since all other methods need the same account information.
Generally speaking it will be more difficult for you to unit test your code if you use a lot of static methods (people consider it easier to mock an object using something like Mockito than mock a static method using something like Powermock).
However, if you do not care about that, and the method uses no instance data of the class it's in, you may as well make it static.
Yes.
That's the correct approach and at least I follow that.
For example, the utility methods should be made static.
But, mostly there are many future requirments and changes required, and we can't forsee all of them today. so instance should be preferred over static. until unless you are following some design pattern.
as such you can go with any kind of implementation. But rather than possibility, the criteria should be the requirement.
if you have some operations to be performed class-wide u should opt for static methods. say for example, if you have to generate some uniqueID per instance, or you have to initialize any thing that the instances would use like display or db-driver.
in other cases, instance methods are preferred where operations are instance specific.
Methods should be made static only when it makes sense for them to be static. Static methods belong to the class and not to the specific instances of it. Static methods can only use other static features of the class. A static method could not call an instance method or access instance variables for example. If this makes sense for the method you are designing, then it is a good idea to use static.
Also static elements, be it variables or methods, are loaded into memory at class loading time and stay there until the end of execution or when the class-loader unloads/reloads the class it belongs to.
I use Static methods when they are meant to do computations that do not fit in the general object oriented modeling of my application. Usually utility methods such as methods to validate input data or to hold information specific to the entire application execution, or to access points to external databases are good candidates for this.
As best of my knowledge,
If you have such a code or logic that utilize or yield something that is related to particular object state, or in simple words if your logic in side method treats different objects with some different sets of inputs and produces some different set of output, you need to take this method as instance method.
On the other side if your method has such a logic that is common for each object and the input and output doesn't depends upon object's state you should declare it as static but not instance.
Explaination with examples:
Suppose you are organizing a college party and you have to provide a common coupon to the students of all departments,you just need to appoint a person for distributing a common coupon to students(without knowing about his/her department and roll no.) as he/she(person) approaches to the coupon counter.
Now think if you want to give the coupons with different serial numbers according to the departments and roll number of students, the person appointed by you need to get the department name and roll number of student(as input from each and every student)
and according to his/her department and roll number he will create a separate coupon with unique serial number.
First case is an example where we need static method, if we take it as instance method unnecessary it will increase the burden.
Second case is an example of instance method, where you need to treat each student(in sense of object) separately.
This example may looks silly, but I hope it will help you to understand the difference clearly.
I'm 14 and have been learning java for about 4/5 months. I'm coding a game now called super mario winshine and i wanted to know if it is good practice to have a class that is mostly static variables.
The class is the one that holds all the information for the game's level/world. Since I only need one version of this class, and lots of other classes will be using it, I choose to make all the variables static. Is this good practice?
I have considered the fact that i could keep the variables "non-static" and just clone the main object i use for that class, but I thought i would rather sacrifice "O-O" for memory in this case.
As soon as you want to have two or more worlds this will fail. Say, when your first release is a runaway success and you want to add the "parallel universe" expansion set.
In my experience, 90% of the time when marketing says "oh, don't worry, there will only be one Application/Window/Database/User" they are wrong.
ADDED
I would also avoid using a true Singleton pattern with World.getInstance() etc. Those are for the rare cases where it really is an essential requirement that there only be one of something. In your case, you are using it as a convenience, not a requirement.
There is no perfect fix, YMMV, but I'd consider a single static method, something like
World World.getWorld(String name)
and then you call real (non-static) methods on the World that is returned. For V1 of your program, allow null to mean "the default world".
Some might put that method into a class named WorldManager, or, perhaps showing my age, a more clever name like Amber. :-)
It all depends upon what your methods and classes are. There is no problem in defining utility methods as static methods in a class. There is no need to make it a singleton as others are suggesting. Look at the Math class from java.lang package. It has lot of utility methods but it isn't a singleton.
Also check out static imports functionality. Using this you doesn't need to qualify method calls with the class name.
Well, what you are doing is definitely an option. Or you could use a singleton pattern:
public class World {
private static World instance = new World();
private World() {
}
public static World getInstance() {
return instance;
}
}
Now just use World.getInstance() everywhere to have a unique object of this type per application.
I would say it's definitely not a good practice.
I've not seen your code, but having several static variables in a class that other classes access freely seems to indicate that you're not really using object orientation/classes but more just writing procedural code in Java. Classes should generally encapsulate/hide all their variables - static or not - from access from other classes so that other classes don't depend on how the class is implemented.
The static part also causes problems with making threads work (global variables are hard to lock in a good way so that nothing deadlocks) and with unit testing (mocking is all but impossible)
I also agree with the other posters, if you need "global variables", at least make them singletons. That allows you to change strategy easier later and does not lock you to one world.
Edit: I'm definitely not advocating singletons as a good pattern here if someone read it like that, but it does solve some problems with static variables, esp. regarding testing/mocking compared to just statics so I'd say it's a ever so slightly lighter shade of gray :) It is also a pattern that is easier to gradually replace with better patterns by for example using a IoC container.
I think it is fine as long as you don't need anything more sophisticated, in other words, static fields are OK as long as different objects (including subclasses if there will be any) do not need different values.
You code by yourself, refactoring is easy with modern tools, me says don't fix it until it is broken, and focus on the algorithmic aspects of your project.
Perhaps you may think to encapsulate all those static fields within a different static class, as it is a good principle to "keep what changes seperate from what does not". Chances are one day you will want to initiate that static class with different values, for example want to read the initial values from an XML file and/or registry, add behaviour, etc. so instead of a static class you will implement it with a Singleton pattern.
But clearly that is not the concern of today. Till then, enjoy!
You may wish to look into implementing this class as a singleton, while there is nothing particularly wrong with your approach it may lead to some inflexibility further down the road.
Also you should take in to consideration the purpose of static members which is to be a member of the class and 'act' on/with the class not an instance of it. For example the static method in a singleton returns either a new instance of the class if one doesn't already exist or returns the instance, and because the method is static you do not instantiate a new one. This is probably worth a read because it can be somewhat confusing when determining the appropriate use of static members
I'm not sure what you are really talking about from your short description, so I'll try this:
public class Level {
static List<Mushroom> mushrooms;
static List<Coin> coins;
...
}
Is that you were describing?
You asked if this is "good practice" and I can tell you that this looks very odd, so, no, it's not.
You gain absolutely nothing by doing this. You make it impossible to have more than one Level, which brings no advantage, but it could cause trouble in the future.
I didn't understand your last paragraph where you say you made most things static to save memory. You would usually create one Level and it would be passed around (without cloning) to the various classes/methods that read from it or modify it.
I have created an anonymous class in which I declare a few variables and methods. My java teacher tells me to make these private. I don't see how changing the modifier makes any difference since these variables and methods are private to the anonymous class anyway, so I prefer to have no modifier at all. Who is right and what makes more sense? See below for example code where I choose no modifier for 'map' and 'convert' rather than making them private.
Collections.sort(list, new Comparator<String>(){
public int compare(String a, String b){
return convert(a).compareTo(convert(b));
}
Map<String, String> map = new HashMap<String, String>();
String convert(String s) {
String u = map.get(s);
if (u == null)
map.put(s, u = s.toUpperCase());
return u;
}
});
I would be tempted to make them private simply for the fact that if you refactor the code and pull the anonymous class out as a standard class (Intellij, for example, can do this at the click of a button), having private fields is what you really want. You won't have to go and rework your classes to match your standard.
Personally I would make them private (and final where possible) anyway - it's just a good habit to be in in general.
To put it another way: if you had to put an access modifier on (if, say, the keyword package was also used as an access modifier) what would you choose? Private, presumably - after all, you don't actually want to grant any other class access, do you?
Now, having decided that private is the most logically appropriate access modifier, I would make that explicit in the code.
Then again, I'd quite possibly not create an anonymous inner class with a member variable anyway - I'd be tempted to turn that into a named nested class instead.
Your professor is right.
Make all class variable private and expose them via properties (if not anonymous).
The general rule of thumb is to keep member data such as variable including your Map object private.
Default modifier is not the same as the private modifier, there're subtle differences.
However, in your case it's more a religious question whether to make convert() default or private. I don't see any advantage in making it private though.
Anyway, your code has a memory leak as the String Cache is never cleared :-P
Also, for even shorter/less code, use the Comparator String.CASE_INSENSITIVE_ORDER:
Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
It really doesn't matter, but it's probably a good idea to keep your teacher happy as he/she will be grading you.
I'd say it's a matter of style. You can't access the member map outside out of the anonymous class, but it might be best to define them as private for consistency with other classes.
If this were my code, I would say that if a class is complicated enough to need data members, it might be worth pulling it out into a separate class, in which case I'd certainly make the data members private.
The key point is when you say "I don't see how changing the modifier makes any difference since these variables and methods are private to the anonymous class anyway"... you're assuming a lot about how your class is going to be used. Treat every class like it will be passed around and used in a variety of ways, in other words, use modifiers as appropriate. Besides, it makes the intent of class clear. It's not like Java is a terse language anyway, so you might as well be clear.
I don't see much benefit to marking things private just for the hell of it. It won't really gain you anything and someone reading the code might attach some significance to the choice when there really isn't any.
I would question the need for all this complexity. Take a look at: String.compareToIgnoreCase()
You want these fields to be private, so mark them private.If a member is marked neither public not private then something suspicious is going on. Also mark fields that shouldn't change final. Keeping things standardised means less thinking, or at least less thinking on the irrelevant, and less to change when modifying code.
From a language point of view, the only real difference is that if you have extended a base class in the same package, you have now hidden fields or overridden "package-private" (default access) methods. The members can also be accessed via reflection (without setAccessible) by code in the same package (this can have mobile-code security implications).
difference between default and protected.
protected:
object/method is accessible to all classes that are in the same package, and also accessible to sub/extension classes.
default:
object/method is accessible to all classes that are in the same package.
What is your intention of your object/method and code modifier accordingly.
Do not allow yourself to be confused when you come back to the code after six months because in huge projects you want to know that that object/method is or is not accessed anywhere else.
In three weeks, not just months, you would forget what the intended accessibility of those objects, 101% guaranteed. Then if you had a huge project and you had a hundred modifiers that were not specific and you desperately wanted to update the code, you would be frustrated by the compulsion to run reference check on those 100 objects/methods. May be someone took your jar and found the hidden cookies in them and used them, then you changed your code and broke someone's code.
Code your modifiers according to your intention unless you are either one or more of these:
you have no further desire to work
in large java projects.
you are a
extremely intelligent high
functioning autistic person who has
an indexed memory of every event of
your life and can write a completely functional peer-peer file sharing service
within two weeks on a lap top in a
coffee shop.
you deliberately use it
as another tool to obfuscate your
code.
I'm learning Java (and OOP) and although it might irrelevant for where I'm at right now, I was wondering if SO could share some common pitfalls or good design practices.
One important thing to remember is that static methods cannot be overridden by a subclass. References to a static method in your code essentially tie it to that implementation. When using instance methods, behavior can be varied based on the type of the instance. You can take advantage of polymorphism. Static methods are more suited to utilitarian types of operations where the behavior is set in stone. Things like base 64 encoding or calculating a checksum for instance.
I don't think any of the answers get to the heart of the OO reason of when to choose one or the other. Sure, use an instance method when you need to deal with instance members, but you could make all of your members public and then code a static method that takes in an instance of the class as an argument. Hello C.
You need to think about the messages the object you are designing responds to. Those will always be your instance methods. If you think about your objects this way, you'll almost never have static methods. Static members are ok in certain circumstances.
Notable exceptions that come to mind are the Factory Method and Singleton (use sparingly) patterns. Exercise caution when you are tempted to write a "helper" class, for from there, it is a slippery slope into procedural programming.
If the implementation of a method can be expressed completely in terms of the public interface (without downcasting) of your class, then it may be a good candidate for a static "utility" method. This allows you to maintain a minimal interface while still providing the convenience methods that clients of the code may use a lot. As Scott Meyers explains, this approach encourages encapsulation by minimizing the amount of code impacted by a change to the internal implementation of a class. Here's another interesting article by Herb Sutter picking apart std::basic_string deciding what methods should be members and what shouldn't.
In a language like Java or C++, I'll admit that the static methods make the code less elegant so there's still a tradeoff. In C#, extension methods can give you the best of both worlds.
If the operation will need to be overridden by a sub-class for some reason, then of course it must be an instance method in which case you'll need to think about all the factors that go into designing a class for inheritance.
My rule of thumb is: if the method performs anything related to a specific instance of a class, regardless of whether it needs to use class instance variables. If you can consider a situation where you might need to use a certain method without necessarily referring to an instance of the class, then the method should definitely be static (class). If this method also happens to need to make use of instance variables in certain cases, then it is probably best to create a separate instance method that calls the static method and passes the instance variables. Performance-wise I believe there is negligible difference (at least in .NET, though I would imagine it would be very similar for Java).
If you keep state ( a value ) of an object and the method is used to access, or modify the state then you should use an instance method.
Even if the method does not alter the state ( an utility function ) I would recommend you to use an instance method. Mostly because this way you can have a subclass that perform a different action.
For the rest you could use an static method.
:)
This thread looks relevant: Method can be made static, but should it? The difference's between C# and Java won't impact its relevance (I think).
Your default choice should be an instance method.
If it uses an instance variable it must be an instance method.
If not, it's up to you, but if you find yourself with a lot of static methods and/or static non-final variables, you probably want to extract all the static stuff into a new class instance. (A bunch of static methods and members is a singleton, but a really annoying one, having a real singleton object would be better--a regular object that there happens to be one of, the best!).
Basically, the rule of thumb is if it uses any data specific to the object, instance. So Math.max is static but BigInteger.bitCount() is instance. It obviously gets more complicated as your domain model does, and there are border-line cases, but the general idea is simple.
I would use an instance method by default. The advantage is that behavior can be overridden in a subclass or if you are coding against interfaces, an alternative implementation of the collaborator can be used. This is really useful for flexibility in testing code.
Static references are baked into your implementation and can't change. I find static useful for short utility methods. If the contents of your static method are very large, you may want to think about breaking responsibility into one or more separate objects and letting those collaborate with the client code as object instances.
IMHO, if you can make it a static method (without having to change it structure) then make it a static method. It is faster, and simpler.
If you know you will want to override the method, I suggest you write a unit test where you actually do this and so it is no longer appropriate to make it static. If that sounds like too much hard work, then don't make it an instance method.
Generally, You shouldn't add functionality as soon as you imagine a use one day (that way madness lies), you should only add functionality you know you actually need.
For a longer explanation...
http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It
http://c2.com/xp/YouArentGonnaNeedIt.html
the issue with static methods is that you are breaking one of the core Object Oriented principles as you are coupled to an implementation. You want to support the open close principle and have your class implement an interface that describes the dependency (in a behavioral abstract sense) and then have your classes depend on that innterface. Much easier to extend after that point going forward . ..
My static methods are always one of the following:
Private "helper" methods that evaluate a formula useful only to that class.
Factory methods (Foo.getInstance() etc.)
In a "utility" class that is final, has a private constructor and contains nothing other than public static methods (e.g. com.google.common.collect.Maps)
I will not make a method static just because it does not refer to any instance variables.