Static members vs instance members - java

If I need to declare just some constants to use in my class, and there is no real need for declaring them as static, i.e. there will no be several instances sharing that member, is there any sense to declare them as static? Is there a "cost difference" between using static and instance members? Please give information about both java and C#.
And also, is there a difference between java's static members and C#'s static members?

I need to declare just some constants to use in my class
No Idea about Java but in C# constant member's are implicitly static in nature.
See MSDN Document: Constants (C# Programming Guide) for more information. Quoting from the referred document:
Constants are accessed as if they were static fields because the value
of the constant is the same for all instances of the type. You do not
use the static keyword to declare them.

I generally declare every constant in my applications as a private static final variable, for a number of reasons.
Consistency. It's clear to myself and others what are the default core constant definitions are in my application. I can keep them all grouped together, and it's very easy to navigate over to them if they need to be modified. Because they're static, these changes ripple down through every call. This safegaurds you from making accidentally multiple definitions of the same constant.
Performance. If I have a constant that's never changed, there's no point in constantly allocating memory for it during a method call. It's allocated once when a reference to the class is made, and then you're done with it. There that memory remains references until all references to the class are done with.
Good practice. There's a convention in programming where dependencies of should be as highly decoupled as possible. When you declare a function or variable as static, you enforce that it must be interacted with in a static way, i.e. independently of a runtime instance. Without this dependency of a class encapsulating member variables at runtime, you can more precisely control interaction with that class, because it ensures you define precise rules on how a class can be interacted with. You find that the more constants and methods you can declare as static, the more flexible your software becomes because there's little confusion over how certain values and behaviours are supposed to be manipulated.
Exposure. Some functions or constants you define may be useful to other parts of your application. This means you can take advantage of functionality without the requirement for using a runtime instance. For example, the quadratic formula is the same everywhere, so why should it belong to a single instance at all? The same goes for constants, like the speed of light.
Personally, I always declare all functionality of my application as private static. If it makes sense for a class to use that functionality as part of it's operation, then the programmer can wrap the method call in another method and provide the appropriate member variable data. If another part of your application needs to use that static function, all you need to do is increase the visibility of the function.

In Java, constants are not implicity static; constants are not an actual language specification, so constants in Java are simply variables that we refer to as constants.
In C#, constants are implicitly static. Constants are part of the language specification, and states in the documentation:
Constants are accessed as if they were static fields because the value of the constant is the same for all instances of the type. You do not use the static keyword to declare them.

if you will declare constant as static than your program will use only one memory location to store this constant value, and if you will not use static than every object will store this constant separately. As you said there are no several instances, in this case either you specify constant as static or declare it simply both will be of same cost.

Related

Do Java classes have an instance on machine (JVM) level if they contain only static methods and fields?

Do Java classes have an instance on machine (JVM) level if they contain only static methods and fields?
And if yes, what are the effects of static methods and fields when doing multithreading? Any rules of thumb?
Yes, for each loaded class in the JVM there is an instance of java.lang.Class. It does not matter whether they only contain static methods/fields or instance methods/fields as well.
And this does not have any extra impact on multi-threading beyond what instance fields and methods already have. That is, as long as you realise that the value of a static field is shared between all instances.
If you want to synchronize, you need to synchronize on the java.lang.Class instance for the class (or if the method is a static method inside said class, it can have the 'synchronized' modifier on the static method to have the same effect as synchronizing on the java.lang.Class instance for the class).
One extra thing to note is that a class with the same name can be loaded by more than one classloader at the same time in the JVM- hence classes in Java are not uniquely identifier by their fully-qualified name, instead they are uniquely identifier by the combination of java.lang.ClassLoader instance used to load the class, and the fully-qualified name.
Static methods and variables are at the class level in Java, not instance level.
All shared, writable state needs to be synchronized and thread safe, regardless of static or instance.
There are no such thing as "static classes" in java. There are inner static classes, but i presume that your question its not about this type of classes.
Classes are loaded once per classloader not per Virtual Machine, this is an important diference, for example applications server like tomcat have different classloaders per application deployed, this way each application is independent (not completely independent, but better than nothing).
The effects for multithreading are the effects of shared data structures in multithreading, nothing special in java. There are a lot of books in this subject like http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601 (centered in java) or http://pragprog.com/book/pb7con/seven-concurrency-models-in-seven-weeks (that explain difference concurrency models, really interesting book)
Yes, a class with static fields and methods has exactly one instance, which is accessed through a static call.
If you use static methods, the variables declared within the method are isolated and don't need to be synchronized (the same as in C#: C# : What if a static method is called from multiple threads?).
But when your classes have static variables and you access them within a static method, there is a trade off: When doing multithreading, the access to the static variables must be synchronized. That's the reason why the singleton pattern doesn't work as good as some believe: Instantiation costs, even more if it's only singlethreaded.
Rules of thumb? Static methods with no static class variables are always good. But static classes with variables can become very evil when doing multithreading. Therefore beware of static bottlenecks!

Is there a point to having a class with all non-static methods but no non-static fields? (or all static fields and methods along with a constructor)

I am looking at other peoples' code.
I see a class with no non-static fields but in which most of the methods are non-static, requiring you to make an object to access methods that effectively operate statically.
Is there a possible reason for this, that I am just not understanding?
EDIT
Someone asked for examples. Here is some more info.
For instance there is a file manager class. The only fields are static and are Comparators. There are some methods to do things like sort files in a list, count files, copy files, move files to an archive folder, delete files older than a certain time, or create files (basically take a base name as string, and return a File with given base name and date/time tacked on the end.)
9 non-static methods
5 static methods
I don't see a particular rhyme reason for the ones that are static vs non.
One particularly odd thing is that there are two methods for removing files. One that removes a file no matter what, and one that only removes it if it is empty. The former is a static method while the latter is not. They contain the same exact code except the later first checks if the file.length is 0.
Another odd one is a class that does encryption - all fields and methods are static but it has a constructor that does nothing. And an init() method that checks if a static variable contains an object of itself and if not instantiates an object of itself into that field that is then never actually used. (It seems this is done with a lot of classes - init methods that check for an object of itself in a static variable and if not instantiate itself)
private static File keyfile;
private static String KEYFILE = "enc.key";
private static Scrambler sc;
It has methods to encrypt and decrypt and some methods for dealing with key and file.
Does this make sense to anyone? Am I just not understanding the purpose for this stuff? Or does it seem weird?
Objects don't have to have state. It's a legitimate use case to create an instance of a class with only behaviour.
Why bother to create an instance ? So you can create one and pass it around e.g. imagine some form of calculator which adheres to a particular interface but each instance performs a calculation differently. Different implements of the interface would perform calculations differently.
I quite often create classes with non-static methods and no members. It allows me to encapsulate behaviour, and I can often add members later as the implementation may demand in the future (including non-functionality related stuff such as instrumentation) I don't normally make these methods static since that restricts my future flexibility.
You can certainly do it that way. You should look carefully at what the instance methods are doing. It's perfectly okay if they're all operating only on parameters passed in and static final static class constants.
If that's the case, it's possible to make all those methods static. That's just a choice. I don't know how the original developers would justify either one. Maybe you should ask them.
Let me rephrase this question a bit,
Even though methods are non-static why would one declare fields as static?
I have taken below quoting from Java Docs,
Sometimes, you want to have variables that are common to all objects. This is
accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory. Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class.
For example, suppose you want to create a number of Bicycle objects and assign each a serial number, beginning with 1 for the first object. This ID number is unique to each object and is therefore an instance variable. At the same time, you need a field to keep track of how many Bicycle objects have been created so that you know what ID to assign to the next one. Such a field is not related to any individual object, but to the class as a whole.
For Bicycle example, kindly refer the Java Docs.
Making all methods non-static allows you to override them. This makes it a lot easier to use this class in testing, because instead of the actual implementation you can use a mock that behaves as you want it for the tests. Static methods are, in my book, a code smell and should be avoided unless there's a good reason (e.g. quite trivial utility methods).
Also, at some point in the future you might want to change the behaviour of the methods in some situation, e.g. in the form of a strategy.
In the case of your encryption class, you might want to hand your class an instance of the encryption class to handle encrypting/decrypting, but be able to configure the details in some other place. That would allow you to change the algorithm and much more easily test your own code without also having to test the encryption.

Criteria for Java static methods?

Someone told me:
If you are using Eclipse and don't see any blue words (i.e. member variables) in your methods, then those methods should really be static methods, as long as the parameters (if there are any) are primitive types, or (in the case of object references) are immutable and/or thread-safe.
Is there any other criteria that a Java developer should consider when deciding whether an instance method should really be a static method instead?
Put it simply, if it is pure "helper/function" which does not modify internal state of object, it's good candidate for static method.
... unless you plan to subclass and override the method.
as long as the parameters (if there are any) are primitive types, or (in the case of object references) are immutable and/or thread-safe.
I don't see why that is relevant. Any thread-safety considerations are exactly the same whether you make the method static or not. A static method with only immutable parameters (that also does not mess with static fields of the class) is thread-safe. If the parameters are not immutable and the method changes them and this becomes un-thread-safe, then making this an instance method won't help at all.
If you don't need an instance of an object to call the method it should be static. That is: If you only work with the parameters and no members of an object. Usually those are collected in utility or helper classes that are never instantiated (secure by declaring a private default constructor).
ps: concerning "blue words": You should always use the this. to access member variables and not count on your IDE as the code becomes quite unreadable once you use a simple viewer/editor.
Any function which you plan to use in a global way for all your instances can be made static

How does static work in a multi threaded environment?

If I have static class, how does jvm guarantee it is initialized once? What happens when two threads simultaneously try to access this first time? Is this feature language invariant?
EDIT : It is about a class which has static variables.
The JVM guarantees that ANY class is initialised exactly once.
What exact low-level mechanism is uses to do this is really JVM-specific, but the thing you need to know as a programmer is that it IS thread-safe per se to attempt to access/initialise the same class from different threads. (Of course, that just goes for class-loading: in terms of accessing any immutable data, be it static or of a particular instance, you need to take appropriate measures.)
You can have a static nested class and the behaves like any other class.
I assume you are referring to static code/blocks and class initialisation. The JVM guarantees that a class will be loaded by only one thread. Since its builtin to the JVM I don't imagine any languages wouldn't use it.
First off, the static keyword is not that commonly used in class declarations, although it can be used there, but means something different than it does for variables or methods.
Did you really want to know about static classes? Or was it a question about static variables/methods?
Static anything is initialized when the class is loaded, not when the first thread attempts to access it. However, static for a class is not the same as static for a data member or function/method. See this article for more information about that. If you are asking about data members, if they are static, then they are considered to be "class variables" or "class methods" not "object variables" (see this article from Oracle for that discussion). It accomplishes that by making them part of the class object itself rather than the instances. There is only ever one class object for any given class.
With regards to your question about other languages: no, static can mean many different things depending on the language.

Static Methods or Not? Global variables?

I want to know what way is more efficient.
No global variables, passing variables through parameters, having all methods static
No global variables, having only main method static and creating class object in main to access methods
Use only global variables, having only main method static and creating class object in main to access methods
I am currently using method 3 but I want to know what is more efficient. This class will not be used by any other class outside of it, it pretty much stands alone.
Example of my code structure:
public class myClass {
private int globalVariable;
public static void main(String args[]) {
myClass c;
c.someMethod(); // Changes global variable from method
System.out.println(someMethod); // Prints solution
}
public void someMethod() {...}
}
No class is an island.
There are no silver-bullets, at least its very true in programming.
Premature optimisation is the root of all evil.
In Java we don't have global variables. We only have class variables, instance variables, and method variables.
[Edit]
I am trying to explain here my last point. In fact, bringing the discussion, that is going-on in comments below, to the actual post.
First look at this, an SO thread of C#. There folks are also suggesting the same thing, which is,
There are no global variables in C#". A variable is always locally-scoped. The fundamental unit of code is the class, and within a class you have fields, methods, and properties
I would personally recommend erasing the phrase "global variable" from your vocabulary (this is in the comment section of the original question)
So, here we go.
retort: Classes are globally scoped, and thus all class variables are globally scoped. Hence should be called global.
counter-retort: Not all classes are globally scoped. A class can be package-private. Therefore, the static variables in there will not be visible outside the package. Hence, should not be called as global. Furthermore, classes can be nested, thus can be private as well and definitely can have some static variables but those wouldn't be called global.
retort: public classes are globally scoped, and thus all class variables are globally scoped.
counter-retort: Not exactly. I would like to move the previous argument here but on a variable level. No matter if the class itself is public. The variables in there can be protected, package-private and private. Hence, static variables will not be global in that case.
Now, if you like to call public static variable in public static class, as global then call it by any means. But consider this, when you create a new ClassLoader (as a child of the bootstrap ClassLoader) and load a class that you've already loaded. Then that results in a "very new copy of the class" -- complete with its own new set of statics. Very "un-global", indeed. However, we don't use the word global in Java because it tends to confuse the things and then we need to come with whole lot of explanations just to make everything clear. Folks rightly like to explain the feature of global variables in Java by static variables. There is no problem in that. If you have some problem/code in any other language and that is using global variables and you need to convert that code to Java, then you most likely make use of static variable as an alternative.
A couple of examples I like to render here
When I started Java, instructors like to explain the difference of passing object type variable and primitive variables. And they constantly use the term objects are pass-by-reference, whereas primitives are pass-by-value. Students found this explanation quite confusing. So, we came up with the notion that everything in Java is pass-by-value. And we explain that for objects references are pass-by-value. It becomes much more clear and simple.
Similarly, there are languages which support multiple-inheritance. But Java doesn't, again arguably speaking. But folks tend to explain that feature using interfaces. They explain it by class implementing many interfaces, and call it multiple-inheritance. That's perfectly fine. But what the class, actually, receives by inheriting a number of interfaces. Frankly speaking, nothing. Why?
. Because all the variables in interfaces are implicitly public, final and static, which apparently means those belongs to the class and anyone can access those. Now we can say that perhaps there would be some inner class in the interface, then the class implementing the interface will have it. But again that will be static implicitly and will belong to the interface. Therefore, all what the class will get are methods. And don't forget just the definition and the contract which says, "the class implementing this interface must provide the implementation of all methods or declare itself abstract". Hence, that class will only get responsibilities and nothing much. But that solves our problems in a brilliant way.
Bottom line
Therefore, we say
There are no global variables in Java
Java doesn't support multiple-inheritance, but something like that can be achieved by implementing multiple interfaces. And that really works
There is nothing pass-by-reference in Java, but references are pass-by-value
Now I like to site few more places
Java does not support global, universally accessible variables. You can get the same sorts of effects with classes that have static variables [Ref]
However, extern in ObjectiveC is not an alternative to a class-scoped static variable in Java, in fact it is more like a global variable … so use with caution. [Ref]
In place of global variables as in C/C++, Java allows variables in a class to be declared static [Ref]
Furthermore, the overuse of static members can lead to problems similar to those experienced in languages like C and C++ that support global variables and global functions. [Ref]
All these are inferring one and the same idea. Which is Java doesn't support global variables.
Hell, I wrote that much. Sorry folks.
Performance doesn't matter. You want it as easy to read as possible.
I would do 2 as much as you can. When you really need constants and statics, make constants and statics.
For example, a null safe trim makes a good static method. New upping a StringTrimmer is silly. Putting if null then x else z in 1000 others is silly.
I think this was settled back in 1956 and 1958, when people invented Lisp and ALGOL58 and pondered about modularity, referential transparency, and sound code structure as means to tackle impenetrable spaghetti code that rely on global variables (and who tend to exhibit the software equivalent of the Heisenberg uncertainty principle.)
I mean seriously, this is 2011 and we still wonder about whether to use global variables over encapsulated fields or parameter passing for quote-n-quote efficiency. I mean, seriously.
I may sound arrogant (so be it), but I'll say this:
I can understand some spaces where you have to make some sort of global variable trade-offs (.ie. very resource constrained embedded platforms, for example). I can understand if a person that is just starting in CS (say a freshman) asks this.
But if someone beyond freshman level (let alone someone that does coding for a living and not coding in the most resource barren of environments) asks or even remotely thinks about this as an acceptable thing to do should seriously reconsider going back to the basics (or reconsider this profession - we have too much craptacular code already.)
Short and concise answer: No, it makes no sense. There are no noticeable games. It is not worth it. It leads to craptacular code. And all of these have been known for 50 years now.

Categories