Why shouldn't static classes store states? (Java) - java

Firstly, I would like to briefly define a state to make sure we're on the same page. (please correct me if I'm wrong, or if you have anything to add)
Mutable variables/objects in the class.
Likely to be used in other classes, therefore creating a reference.
I've heard the main use of static in classes is for utility classes, which basically just provide global access to common methods -- and when states need to be stored, you should use a Singleton. However, I do not understand exactly why states are BAD for static classes? (Please correct me if this ideology is wrong)

Related

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.

Creating Immutable Objects in Java

I'd like to create a few immutable objects for my codebase. What's the best way to really deliver the message that a given class is intended to be immutable? Should I make all of my fields final, and initialize during object construction? (This seems really awkward...) Should I create some Immutable interface, and have objects implement it? (Since Java doesn't have some standard interface behind this, I thought they had some other way of dealing with it.) What's the standard way this is dealt with? (If it's simply done by adding a bunch of comments around the fields exclaiming that they shouldn't be modified once initialized, that's fine too.)
Should I make all of my fields final, and initialize during object construction?
Yes. And ensure that those types are themselves immutable, or that you create copies when you return values from getter methods. And make the class itself final. (Otherwise your class on its own may be immutable, but that doesn't mean that any instance of your class would be immutable - because it could be an instance of a mutable subclass.)
(This seems really awkward...)
It's hard to know what to suggest without knowing how you find it to be awkward - but the builder pattern can often be useful. I usually use a nested static class for that, often with a static factory method. So you end up with:
Foo foo = Foo.newBuilder()
.setName("asd")
.setPoints(10)
.setOtherThings("whatever")
.build();
Yes and no. Making all fields final is not a guarantee in and of itself. If you'd like to get really in-depth with this there are a number of chapters in Effective Java by Joshua Bloch dealing with immutability and the considerations involved. Item 15 in Effective Java covers the bulk of it and references the other items in question.
He offers these five steps:
Don’t provide any methods that modify the object’s state (known as muta-
tors).
Ensure that the class can’t be extended.
Make all fields final.
Make all fields private.
Ensure exclusive access to any mutable components.
One way to learn how to do all of this is to see how the language designers make classes immutable by reviewing the source for classes like String which are immutable (for example see http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/String.java).
Write a unit test that will fail if your coworkers make the class mutable.
Using Mutability Detector, you can write a test like this:
import static org.mutabilitydetector.unittesting.MutabilityAssert.assertImmutable;
#Test public void isImmutable() {
assertImmutable(MyImmutableThing.class)
}
If a coworker comes along, and, for example, adds a setter method to your class, the test will fail. Your use case is one of the core purposes of Mutability Detector.
Disclaimer: I wrote it.

java - public access vs accessor methods [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why use getters and setters?
I'm reading the Java for Dummies 2nd edition, and it says that it's better to define accessor methods for class's variables instead of making them public. Is that true?
Yes.
Defining accessor methods allows you greater flexibility. For instance, you can make it publicly readable, but only privately writable.
Here's a Skeet answer to this particular question. He suggests always making your fields private
Yes, it's a convention.
It allow you to control how other classes will access the members (that are usually private). For example you can start with a basic get/set that return and set the value. But maybe later in the project you will want to add more control. in this case you will only have to change get/set method instead of refractoring all your project.
I'd go as far as to say it is better not to even have accessor methods either, if possible. Make the class do work on its own state rather than exposing it for another class to work with.
If you do have to expose state, accessor methods give you the opportunity to return a copy of the state rather than the actual object. This way calling classes wont be able to modify the state from outside, avoiding the issue of invariants being broken.
This is true!
In Java, it is common practice to declare class variables private, and then write public accessor and mutuator methods to control them outside of the class.
It is usually good to make accessor methods, to regulate the data any other class (and anybody) can use.
Particularly in big projects, you want other classes only to use just a few of the many variables in the class, so you only make a few getter methods.
On the second hand, it makes the code cleaner, it is easier to see what is happening. Thirdly, it is harder to create your own bugs in your program by using the wrong variable, because in other classes there are less possible variables to choose from.
I recommend reading about object oriented programming philosophy:
wikipedia:
When you define accessors you can write there some extra logic protecting the state of your objects.

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.

Why use a singleton instead of static methods?

I have never found good answers to these simple questions about helper/utility classes:
Why would I create a singleton (stateless) instead of using static methods?
Why would an object instance be needed if an object has no state?
Often, singletons are used to introduce some kind of global state to an application. (More often than really necessary, to be honest, but that's a topic for another time.)
However, there are a few corner cases where even a stateless singleton can be useful:
You expect to extend it with state in the foreseeable future.
You need an object instance for some particular technical reason. Example: Synchonization objects for the C# lock or the Java synchronized statement.
You need inheritance, i.e., you want to be able to easily replace your singleton with another one using the same interface but a different implementation.Example: The Toolkit.getDefaultToolkit() method in Java will return a singleton whose exact type is system dependent.
You want reference equality for a sentinel value.Example: DBNull.Value in C#.
I could see a case for a stateless singleton being used instead of a static methods class, namely for Dependency Injection.
If you have a helper class of utility functions that you're using directly, it creates a hidden dependency; you have no control over who can use it, or where. Injecting that same helper class via a stateless singleton instance lets you control where and how it's being used, and replace it / mock it / etc. when you need to.
Making it a singleton instance simply ensures that you're not allocating any more objects of the type than necessary (since you only ever need one).
Actually i've found another answer not mentionned here: static methods are harder to test.
It seems most test frameworks work great for mocking instance methods but many of them no not handle in a decent way the mock of static methods.
In most programming languages classes elude a lot of the type system. While a class, with its static methods and variables is an object, it very often cannot implement an interface or extend other classes. For that reason, it cannot be used in a polymorphic manner, since it cannot be the subtype of another type. For example, if you have an interface IFooable, that is required by several method signatures of other classes, the class object StaticFoo cannot be used in place of IFooable, whereas FooSingleton.getInstance() can (assuming, FooSingleton implements IFooable).
Please note, that, as I commented on Heinzi's answer, a singleton is a pattern to control instantiation. It replaces new Class() with Class.getInstance(), which gives the author of Class more control over instances, which he can use to prevent the creation of unneccessary instances. The singleton is just a very special case of the factory pattern and should be treated as such. Common use makes it rather the special case of global registries, which often ends up bad, because global registries should not be used just willy-nilly.
If you plan to provide global helper functions, then static methods will work just fine. The class will not act as class, but rather just as a namespace. I suggest, you preserve high cohesion, or you might end up with weirdest coupling issues.
greetz
back2dos
There is a trade-off between using which one. Singletons may or may not have state and they refer to objects. If they are not keeping state and only used for global access, then static is better as these methods will be faster. But if you want to utilize objects and OOP concepts (Inheritance polymorphism), then singleton is better.
Consider an example: java.lang.Runtime is a singleton class in java. This class allows different implementations for each JVM. The implementation is single per JVM. If this class would have been static, we cannot pass different implementations based on JVM.
I found this link really helpful: http://javarevisited.blogspot.com/2013/03/difference-between-singleton-pattern-vs-static-class-java.html?
Hope it helps!!
Singleton is not stateless, it holds the global state.
Some reasons which I can think of using Singleton are:
To avoid memory leaks
To provide the same state for all modules in an application e.g database connection
For me "Want Object State use Singleton, Want Function use static method"
It depends on what you want. Whenever you want the object state (e.g. Polymorphism like Null state instead of null, or default state), singleton is the appropriate choice for you whereas the static method use when you need function (Receive inputs then return an output).
I recommend for the singleton case, it should be always the same state after it is instantiated. It should neither be clonable, nor receive any value to set into (except static configuration from the file e.g. properties file in java).
P.S. The performance between these 2 are different in milliseconds, so focus on Architecture first.
According to GoF’s book Design Patterns, chapter ‘Singleton’, class operations have the following drawbacks compared to singletons (bold emphasis mine):
More flexible than class operations. Another way to package singleton’s functionality is to use class operations (that is, static member functions in C++ or class methods in Smalltalk). But both of these language techniques make it hard to change a design to allow more than one instance of a class. Moreover, static member functions in C++ are never virtual, so subclasses can’t override them polymorphically.

Categories