I would like to share an object between various instances of objects of the same class.
Conceptually, while my program is running, all the objects of class A access the same object of class B.
I've seen that static is system-wide and that its usage is discouraged. Does that mean that if I've got another program running on the same JVM that instantiates objects of class A, these objects could potentially access the same B object as the one accessed in the previous program?
What are generally the flaws behind using static fields?
Are there any alternatives (that do not require a huge effort of implementation)?
Static doesn't quite mean "shared by all instances" - it means "not related to a particular instance at all". In other words, you could get at the static field in class A without ever creating any instances.
As for running two programs within the same JVM - it really depends on exactly what you mean by "running two programs". The static field is effectively associated with the class object, which is in turn associated with a classloader. So if these two programs use separate classloader instances, you'll have two independent static variables. If they both use the same classloader, then there'll only be one so they'll see each other's changes.
As for an alternative - there are various options. One is to pass the reference to the "shared" object to the constructor of each object you create which needs it. It will then need to store that reference for later. This can be a bit of a pain and suck up a bit more memory than a static approach, but it does make for easy testability.
Static methods and members are discouraged because they're so frequently misused, but this sounds like a situation where static is the correct way to go. As to static shared across multiple programs, this is not the case. Each program runs in a completely separate environment.
What you are looking for is called the Singleton Pattern.
Assuming everything is in the same class loader, then why not use the monostate pattern to do this?
Your shared static is hidden in the monostate:
public class Monostate {
private static String str = "Default";
public String getString() {
return str;
}
public void setString(String s) {
str = s;
}
}
Then you are free to create as many instances of the monostate as you like, but they all share the same underlying object due to the static reference.
Monostate mono = new Monostate();
mono.setString("Fred");
System.out.println(mono.getString());
Related
I'm looking at chapter 1 of Effective Java(3th ed, Joshua J. Bloch)
and It says using a static method is better than constructor.
But I understand that static is loaded in memory when classloader initiates,
and in normal case the static members are not removed by garbage collector
until the class unloaded.
So if I understood right, when I use more and more classes which have static method,
It consumes more memory, am I right?
Is that memory timid to concern, or there are other reasons to use them nevertheless?
Static member variables are not garbage collected (assuming the classloader is still alive), since the class itself will always hold a reference to it. The same is not true of methods.
Static methods (a.k.a factory methods) are sometimes preferred for a few reasons.
You can name them how you want: Imagine the following constructor: public Hyperlink(String string){...}. It is not clear what the string actually refers to. Is it the text to be made into the link? Is it the URL? Imagine instead the static factory public Hyperlink.fromURL(String string){...}. Much clearer.
Caching - the new keyword always creates a new object, or it throws an exception. There is no way to return an object that already exists in a cache somewhere. With a static factory, you could first check that the object does not already exist, and retrieve it if it does, and call a constructor if it doesn't.
Polymorphism - Consider the classes Animal and Dog extends Animal. The constructor public Animal(String species){...} always returns an Animal object. Dog dog = Animal.fromSpecies(String species); however, is valid.
There are of course reasons to use constructors, but personally, I will always go for a static factory method for anything vaguely complex.
Concerning memory usage, the cost of storing methods, except in very large projects or very constrained systems is negligible. Load time is another issue, but not one that is improved by avoiding static methods.
An instance variable is one per Object, every object has its own copy of instance variable.
A static variable is one per Class, every object of that class shares the same Static variable.
class MyStaticClass{
private static int myStaticInt;
public static int getMyStaticInt() {return myStaticInt;}
}
class MyInstanceClass{
private int myNonStaticInt;
public int getMyNonStaticInt() {return myNonStaticInt;}
}
Is there a performance difference between either? Is it more expensive to call one over the other?
int i = MyStaticClass.getMyStaticInt();
OR:
int i = new MyInstanceClass().getMyNonStaticInt();
It's not a matter of performance. static and instance variables have a different purpose.
Using
int i = new MyInstatnceClass().getMyNonStaticInt();
is almost certainly useless, since each time you call new MyInstatnceClass() you create a new MyInstatnceClass instance, having a new myNonStaticInt instance variable. Since you are not keep a reference to the created instance, you cannot retrieve the same instance variable twice, which makes it useless.
If you need a single copy of a variable to be shared across all instances of the class, static variable is the way to go.
That said, the latter call is also more expansive, since it involves creation and initialization of an instance of your MyInstatnceClass class (in addition to loading and initialzing the class if it's the first access that class).
On the other hand, MyStaticClass.getMyStaticInt() only loads and initializes the class MyStaticClass if it's the first access of that class. It doesn't have to create any instance of that class.
Since instance methods can be polymorphically overridden, a very naive JVM implementation must at least initially use a virtual mehod table to find the appropriate method to call. Classes themselves, however are not polymorphic and class methods cannot be overridden. Due to this, they have a simpler lookup mechanism.
However, real-world JVMs are incredibly smart and can tell which methods are never overridden and optimize this lookup away. In other words, in all but the most contrived instances with non-existent JVMs will there be a difference in performance. Instead, use static methods to represent functionalities relevant to the entire class of objects itself rather than to a single instance thereof.
I have more than 20 commonly used methods in my application. I would like to move that 20 methods into a common class.
Here my doubt is, define all the methods are static or normal method and create a global object to access that normal methods.
class Common {
public String method1() {........}
public String method2() {........}
public String method3() {........}
public String method4() {........}
public String method5() {........}
...
}
Creating object.
class CommonService {
private static Common common;
public static Common getCommon() {
if(null == common) {
common = new common();
}
return common;
}
}
If we create all the methods using static means, all 20 methods are stored in PermGen section of the heap.
But if we follow above method means, only one object can be created and stored in java heap.
Please clarify which one is the best way.
If we create all the methods using static means, all 20 methods are stored in PermGen section of the heap.
Methods are not data, but code. Where code is stored does not depend on whether a method accepts an implicit this parameter or not. If you use the singleton approach, method code will still occupy storage and additionally there will be an instance on the heap.
However, all of the above is irrelevant and you are focusing on a completely wrong aspect of your design. What matters is how the decision will affect the code which uses these methods:
static methods are simple and a great choice for pure functions (which don't depend on any external state);
singletons allow polymorphism, therefore make the methods easier to mock for testing.
You should think about the "best" way in terms of design.
If the methods are used for general purposes, making them static is preferable, as you won't have any state to store and you'll save memory this way.
You should consider other things before deciding if you want to use static methods in your utility class or not. On one hand the utility class will be very easy to test, and it's highly accessible. On the other hand, it's very hard to mock static methods in your test.
If I have a utility class, I would write it as follows:
public final class Common {
private Common() { }
public static int method1() { }
public static int method2() { }
// ...
}
"Common functions" is not quite accurate. It really depends on what you want to do, for example when I make some string utils I make StringUtils class and it has what I need. Whether to make it static or not depends on data to be processed, if one information might be used more than once for a call then answer is simple - use instances.
That depends on what the methods do.
If those methods are just helper methods, that do not alter state then static is probably better because that way you do not have to create an object every time you want to use one of the methods. You can just call Common.method()
However, if the object has state then you should rater use object methods and create a new object when you want to use the methods.
Hope this helps.
If sense of this method is "execute pure function" like mathematical sin(x), cos(x) etc static method is the best.
They belongs to one domain? (range of themats) or to different? (then create more "utility classes" with correct name)
If have state (like many people say) maybe better is singleton.
Shape of the question "i have 20 method in application" and name Common suggest previous (older) design problem, I say "procedural thinking", poor vision of OOP.
Hard to say without code.
I know the difference between static type and other types but I am not sure which is to used where. Now I am using static types in all places to avoid object instantiation. Is it a good idea to use it that way ? Is there any particular disadvantage in using static type in all places ??
EDIT
What do you call this as static String staff ?
This is an excellent question. Usually you should not use static methods/variables unless you know for sure that it's a correct application for it. In object oriented programming (OOP), objects encapsulate data and behavior. Typically, *instance methods are used to manipulate the object's data.
Static methods/variables should only be used for functionality that is not associated with any particular object. A good example of a valid application for static is Math.random().
Some notes about instance and static methods/variables:
Instance variables have access to static and instance variables/methods, but static methods can only access other static variables/methods.
A static variable will always be the same across all instances of a class.
A good book to read that covers this topic is Clean Code by Robert Martin. Highly recommended.
*instance methods are the opposite of static methods. They are associated with a class instance, instead of the class itself.
Addressing your edit, assuming that that's a variable, you'd access it like this:
MyClass.staff = "bob, george, and linda";
System.out.println(MyClass.staff);
Edit: here's a post I made on another forum a while back, with some good answers. It's a PHP forum, but the concepts still apply.
http://forums.devnetwork.net/viewtopic.php?f=1&t=127667
When there are multiple instances of an object, static-typed variables and functions are shared across all instances.
Most logic in any application will be modularized, and will operate on some shared fields. This is the reason why most methods are non-static. The 'fields' in this case can be something as basic as 'firstName', etc. But in other cases, the 'fields' are instances of other classes such as DataAccess (DAO) classes.
Variables i.e. fields should almost never be static, unless they are 'constants'.
A good example where you will be use static methods is a class that transforms Strings, for example:
public class StringUtil{
public static String convertToHex(String orig){
}
}
I know this topic has been discussed and killed over and over again, but I still had one doubt which I was hoping someone could help me with or guide me to a pre-existing post on SO.
In traditional C, static variables are stored in data segments and local variables are stored in the stack. Which I would assume will make static variables more expensive to store and maintain when compared to local variables. Right?
When trying to understand in terms of Java or C#, would this be dis-advantage for static classes when compared to singleton class? Since the entire class is loaded into memory before class initialization, I don't see how it can be an advantage unless we have small inline-able functions.
I love Singleton classes, and would hate to see it become an anti-pattern, I am still looking for all the advantages that come with it...and then loose to the argument of thread-safety among others.
-Ivar
Different from C, the static keyword in Java class definition merely means, This is just a normal class like any other class, but it just happens to be declared inside another class to organize the code. In other words, there is no behavioral difference whatsoever between the following 2 way of declaration*:
a)
class SomeOtherClass {
static class Me {
// If you "upgrade" me to a top-level class....
}
}
b)
class Me {
// I won't behave any different....
}
Class definitions are loaded to memory when the class is used for the first time, and this is true for both "static" and "non-static" classes. There are no difference in how memory will be used, either. In older JVMs, objects were always stored in heap. Modern JVMs do allocate objects on stack when that is possible and beneficial, but this optimization is transparent to the coder (it is not possible to influence this behavior via code), and use of the static keyword does not have any effect on this behavior.
Now, back to your original question, as we have seen we really can't compare static classes and Singleton in Java as they are completely different concept in Java (I'm also not sure how static classes would compare with Singleton, but I will focus on Java in this answer). The static keyword in Java is overloaded and has many meanings, so it can be confusing.
Is Singleton automatically an "anti-pattern"? I don't think so. Abuse of Singleton is, but the Singleton pattern itself can have many good uses. It just happens to be abused a lot. If you have legitimate reason to use the Singleton pattern, there is nothing wrong in using it.
*Note: Why write static at all, you might ask. It turns out "non-static" nested classes have their own somewhat complicated memory management implication, and its use is generally discouraged unless you have a good reason (pls refer to other questions for more info).
class SomeOtherClass {
Stuff stuff;
class Me {
void method(){
// I can access the instance variables of the outer instance
// like this:
System.out.println(SomeOtherClass.this.stuff);
// Just avoid using a non-static nested class unless you
// understand what its use is!
}
}
}
Singleton class is essentially a regular top-level class with a private constructor, to guarantee its singleness. Singleton class itself provides a way to grab its instance. Singleton classes are not very easy to test, therefore we tend to stick with the idea of Just Create Once.
static class is essentially a nested class. A nested class is essentially a outer level class which is nested in another class just for packaging convenience. A top-level class can not be declared as static, in Java at least -- you should try it yourself.
would this be dis-advantage for static
classes when compared to singleton
class?
Your this question became somewhat invalid now, according to the above explanation. Furthermore, a static class (of course nested) can also be a singleton.
Further reading:
Inner class in interface vs in class
The differences between one and the other is the memory management, if your app will have to instantiate a lot of things, that will burn the memory like a charm becoming a memory problem, performance and other things...
this could help...
http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne
http://www.objectmentor.com/resources/articles/SingletonAndMonostate.pdf
I'm afraid it is an anti-pattern:
http://thetechcandy.wordpress.com/2009/12/02/singletons-is-anti-pattern/