Related
According to the Java 8 Language Spec §15.8.2 (quote):
[...]
A class literal evaluates to the Class object for the named type (or for void) as defined by the defining class loader (§12.2) of the class of the current instance.
[...]
Mainly, 'the Class object' insinuates that this is or should be a singleton. Also §12.2 says:
[...]
Well-behaved class loaders maintain these properties:
Given the same name, a good class loader should always return the same class object.
[...]
In fact, using Java 8*, the following** prints true and true:
class Main {
public static void main(String[] args) {
Main main1 = new Main();
Main main2 = new Main();
System.out.println(main1.getClass().equals(main2.getClass()));
System.out.println(main1.getClass() == main2.getClass());
}
}
Is the class loader always 'well-behaved' and why (not)? In other words: are Class instances singleton? The other way around: can a Class of the same type be a different instance?
Notes: I do not refer to the singleton pattern here. However, if the Class implementation follows that pattern, that would be interesting. As a side-step, but by no means the main question: because the singleton pattern's legitimate uses are point of debate, would Java's Class be a good candidate to apply the singleton pattern to?
*:
$ java -version
openjdk version "1.8.0_262"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_262-b10)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.262-b10, mixed mode)
**: my IDE even warns me that the printed expressions are always true.
You are using the term singleton incorrectly.
A singleton implies the existence of only one object of its own class. A Class object is an instance of the class java.lang.Class and there is more than one instance of this class. It’s actually impossible to have only one Class object, as the existence of a Class object does already imply the existence of at least two classes, java.lang.Object and java.lang.Class, so there must be at least two Class objects in the runtime.
Your example is not capable of spotting whether the class loader is well behaved or not. You already mentioned JLS §12.2
Well-behaved class loaders maintain these properties:
Given the same name, a good class loader should always return the same class object.
If a class loader L1 delegates loading of a class C to another loader L2, then for any type T that occurs as the direct superclass or a direct superinterface of C, or as the type of a field in C, or as the type of a formal parameter of a method or constructor in C, or as a return type of a method in C, L1 and L2 should return the same Class object.
A malicious class loader could violate these properties. However, it could not undermine the security of the type system, because the Java Virtual Machine guards against this.
Mind the last sentence. A JVM will guard against violations of these requirements. With the repeated occurrences of the same symbolic references within your example code, there are two possibilities
The JVM remembers the result of the first resolution of this symbolic reference within this context and just reuses it on the next occurrence without asking a class loader again.
The JVM remembers the result of the first resolution of this symbolic reference within this context and compares it with the result of subsequent resolutions of the same reference and throws an error if they mismatch.
Since both approaches imply remembering the result, the first approach is usually used when it comes to resolving the same reference within the same context, as it is simpler and more efficient. When it comes to different symbolic references that resolve to classes using the same reference, the JVM will indeed throw an error when the class loader constraints are violated.
So expressions like Main.class == Main.class or new Main().getClass() == new Main().getClass() will never evaluate to false. Most likely, the resolution of the symbolic reference to Main will go a short-cut, using the same runtime class regardless of what the class loader would do. But even when it does not take the short-cut and the ClassLoader is misbehaving, returning a different class object for the next query, the JVM would detect it and throw an error, so the expression would not evaluate to a boolean result at all. In neither case could it result in false.
In a single classloader, the Class object is the same.
Is the class loader always 'well-behaved' and why (not)?
It really depends on the implementation. If it is done deliberately that always the classloader always returns a new Class-Object, it won't be well-behaved.
At least all classloaders of OpenJDK are well-behaving.
In other words: are Class instances singleton? The other way around: can a Class of the same type be a different instance?
In one single classloader, every Class instance is a singleton. With multiple classloaders, following will evaluate to false:
ClassLoaderA.getInstance().loadClass("foo.Bar")==ClassLoaderB.getInstance().loadClass("foo.Bar");
The other way around: can a Class of the same type be a different instance?
Only if loaded by two different, conforming,well-behaved classloaders.
As a side-step, but by no means the main question: because the singleton pattern's legitimate uses are point of debate, would Java's Class be a good candidate to apply the singleton pattern to?
This is quite opinion-based, but I think, it's no good candidate to apply the singleton pattern, as most singletons are implemented like this:
class Foo{
public static final Foo INSTANCE=new Foo();
private Foo(){
ìf(INSTANCE!=null)
throw new IllegalAccessException("No Foo instances for you!");
}
}
So more that it is really ONE object of a Class, many that only differ by some small things like a different Classloader.
What real (i.e. practical) difference exists between a static class and a singleton pattern?
Both can be invoked without instantiation, both provide only one "Instance" and neither of them is thread-safe. Is there any other difference?
What makes you say that either a singleton or a static method isn't thread-safe? Usually both should be implemented to be thread-safe.
The big difference between a singleton and a bunch of static methods is that singletons can implement interfaces (or derive from useful base classes, although that's less common, in my experience), so you can pass around the singleton as if it were "just another" implementation.
The true answer is by Jon Skeet, on another forum here.
A singleton allows access to a single
created instance - that instance (or
rather, a reference to that instance)
can be passed as a parameter to other
methods, and treated as a normal
object.
A static class allows only static
methods.
Singleton objects are stored in Heap, but static objects are stored in stack.
We can clone (if the designer did not disallow it) the singleton object, but we can not clone the static class object
.
Singleton classes follow the OOP (object oriented principles), static classes do not.
We can implement an interface with a Singleton class, but a class's static methods (or e.g. a C# static class) cannot.
The Singleton pattern has several advantages over static classes. First, a singleton can extend classes and implement interfaces, while a static class cannot (it can extend classes, but it does not inherit their instance members). A singleton can be initialized lazily or asynchronously while a static class is generally initialized when it is first loaded, leading to potential class loader issues. However the most important advantage, though, is that singletons can be handled polymorphically without forcing their users to assume that there is only one instance.
static classes are not for anything that needs state. It is useful for putting a bunch of functions together i.e Math (or Utils in projects). So the class name just gives us a clue where we can find the functions and nothing more.
Singleton is my favorite pattern and I use it to manage something at a single point. It's more flexible than static classes and can maintain it's state. It can implement interfaces, inherit from other classes and allow inheritance.
My rule for choosing between static and singleton:
If there is a bunch of functions that should be kept together, then static is the choice.
Anything else which needs single access to some resources, could be implemented as a singleton.
Static Class:-
You cannot create the instance of static class.
Loaded automatically by the .NET Framework common language runtime (CLR) when the program or namespace containing the class is loaded.
We cannot pass the static class to method.
We cannot inherit Static class to another Static class in C#.
A class having all static methods.
Better performance (static methods are bonded on compile time)
Singleton:-
You can create one instance of the object and reuse it.
Singleton instance is created for the first time when the user requested.
You can create the object of singleton class and pass it to method.
Singleton class does not say any restriction of Inheritance.
We can dispose the objects of a singleton class but not of static class.
Methods can be overridden.
Can be lazy loaded when need (static classes are always loaded).
We can implement interface(static class can not implement interface).
A static class is one that has only static methods, for which a better word would be "functions". The design style embodied in a static class is purely procedural.
Singleton, on the other hand, is a pattern specific to OO design. It is an instance of an object (with all the possibilities inherent in that, such as polymorphism), with a creation procedure that ensures that there is only ever one instance of that particular role over its entire lifetime.
In singleton pattern you can create the singleton as an instance of a derived type, you can't do that with a static class.
Quick Example:
if( useD3D )
IRenderer::instance = new D3DRenderer
else
IRenderer::instance = new OpenGLRenderer
To expand on Jon Skeet's Answer
The big difference between a singleton and a bunch of static methods is that singletons can implement interfaces (or derive from useful base classes, although that's less common IME), so you can pass around the singleton as if it were "just another" implementation.
Singletons are easier to work with when unit testing a class. Wherever you pass singletons as a parameter (constructors, setters or methods) you can instead substitute a mocked or stubbed version of the singleton.
Here's a good article:
http://javarevisited.blogspot.com.au/2013/03/difference-between-singleton-pattern-vs-static-class-java.html
Static classes
a class having all static methods.
better performance (static methods are bonded on compile time)
can't override methods, but can use method hiding. (What is method hiding in Java? Even the JavaDoc explanation is confusing)
public class Animal {
public static void foo() {
System.out.println("Animal");
}
}
public class Cat extends Animal {
public static void foo() { // hides Animal.foo()
System.out.println("Cat");
}
}
Singleton
an object that can only be instantiated once.
methods can be overridden (Why doesn't Java allow overriding of static methods?)
easier to mock then static methods
better at maintaining state
In summary, I would only use static classes for holding util methods, and using Singleton for everything else.
Edits
static classes are lazy loaded as well. Thanks #jmoreno
(When does static class initialization happen?)
method hiding for static classes. Thanks #MaxPeng.
Another advantage of a singleton is that it can easily be serialized, which may be necessary if you need to save its state to disc, or send it somewhere remotely.
I'm not a great OO theorist, but from what I know, I think the only OO feature that static classes lack compared to Singletons is polymorphism.
But if you don't need it, with a static class you can of course have inheritance ( not sure about interface implementation ) and data and function encapsulation.
The comment of Morendil, "The design style embodied in a static class is purely procedural" I may be wrong, but I disagree.
In static methods you can access static members, which would be exactly the same as singleton methods accessing their single instance members.
edit:
I'm actually thinking now that another difference is that a Static class is instantiated at program start* and lives throughout the whole life span of the program, while a singleton is explicitly instantiated at some point and can be destroyed also.
* or it may be instantiated at first use, depending on the language, I think.
To illustrate Jon's point what's shown below cannot be done if Logger was a static class.The class SomeClass expects an instance of ILogger implementation to be passed into its constructor.
Singleton class is important for dependency injection to be possible.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var someClass = new SomeClass(Logger.GetLogger());
}
}
public class SomeClass
{
public SomeClass(ILogger MyLogger)
{
}
}
public class Logger : ILogger
{
private static Logger _logger;
private Logger() { }
public static Logger GetLogger()
{
if (_logger==null)
{
_logger = new Logger();
}
return _logger;
}
public void Log()
{
}
}
public interface ILogger
{
void Log();
}
}
Singleton's are instantiated. It's just that there's only one instance ever created, hence the single in Singleton.
A static class on the other hand can't be instantiated.
Well a singleton is just a normal class that IS instantiated but just once and indirectly from the client code. Static class is not instantiated.
As far as I know static methods (static class must have static methods) are faster than non-static.
Edit:
FxCop Performance rule description:
"Methods which do not access instance data or call instance methods can be marked as static (Shared in VB). After doing so, the compiler will emit non-virtual call sites to these members which will prevent a check at runtime for each call that insures the current object pointer is non-null. This can result in a measurable performance gain for performance-sensitive code. In some cases, the failure to access the current object instance represents a correctness issue."
I don't actually know if this applies also to static methods in static classes.
Main differences are:
Singleton has an instance/object while static class is a bunch of
static methods
Singleton can be extended e.g. through an interface while static
class can't be.
Singleton can be inherited which supports open/close principles in
SOLID principles on the other hand static class can't be inherited
and we need to make changes in itself.
Singleton object can be passed to methods while static class as it
does not have instance can't be passed as parameters
Distinction from static class
JDK has examples of both singleton and static, on the one hand java.lang.Math is a final class with static methods, on the other hand java.lang.Runtime is a singleton class.
Advantages of singleton
If your need to maintain state than singleton pattern is better choice than static class, because maintaining state in static class leads to bugs, especially in concurrent environment, that could lead to race conditions without adequate synchronization parallel modification by multiple threads.
Singleton class can be lazy loaded if its a heavy object, but static class doesn't have such advantages and always eagerly loaded.
With singleton, you can use inheritance and polymorphism to extend a base class, implement an interface and provide different implementations.
Since static methods in Java cannot be overridden, they lead to inflexibility. On the other hand, you can override methods defined in singleton class by extending it.
Disadvantages of static class
It is easier to write unit test for singleton than static class, because you can pass mock object whenever singleton is expected.
Advantages of static class
Static class provides better performance than singleton, because static methods are bonded on compile time.
There are several realization of singleton pattern each one with advantages and disadvantages.
Eager loading singleton
Double-checked locking singleton
Initialization-on-demand holder idiom
The enum based singleton
Detailed description each of them is too verbose so I just put a link to a good article - All you want to know about Singleton
Singleton is better approach from testing perspective.
Unlike static classes , singleton could implement interfaces and you can use mock instance and inject them.
In the example below I will illustrate this.
Suppose you have a method isGoodPrice() which uses a method getPrice() and you implement getPrice() as a method in a singleton.
singleton that’s provide getPrice functionality:
public class SupportedVersionSingelton {
private static ICalculator instance = null;
private SupportedVersionSingelton(){
}
public static ICalculator getInstance(){
if(instance == null){
instance = new SupportedVersionSingelton();
}
return instance;
}
#Override
public int getPrice() {
// calculate price logic here
return 0;
}
}
Use of getPrice:
public class Advisor {
public boolean isGoodDeal(){
boolean isGoodDeal = false;
ICalculator supportedVersion = SupportedVersionSingelton.getInstance();
int price = supportedVersion.getPrice();
// logic to determine if price is a good deal.
if(price < 5){
isGoodDeal = true;
}
return isGoodDeal;
}
}
In case you would like to test the method isGoodPrice , with mocking the getPrice() method you could do it by:
Make your singleton implement an interface and inject it.
public interface ICalculator {
int getPrice();
}
Final Singleton implementation:
public class SupportedVersionSingelton implements ICalculator {
private static ICalculator instance = null;
private SupportedVersionSingelton(){
}
public static ICalculator getInstance(){
if(instance == null){
instance = new SupportedVersionSingelton();
}
return instance;
}
#Override
public int getPrice() {
return 0;
}
// for testing purpose
public static void setInstance(ICalculator mockObject){
if(instance != null ){
instance = mockObject;
}
test class:
public class TestCalculation {
class SupportedVersionDouble implements ICalculator{
#Override
public int getPrice() {
return 1;
}
}
#Before
public void setUp() throws Exception {
ICalculator supportedVersionDouble = new SupportedVersionDouble();
SupportedVersionSingelton.setInstance(supportedVersionDouble);
}
#Test
public void test() {
Advisor advidor = new Advisor();
boolean isGoodDeal = advidor.isGoodDeal();
Assert.assertEquals(isGoodDeal, true);
}
}
In case we take the alternative of using static method for implementing getPrice() , it was difficult to the mock getPrice().
You could mock static with power mock, yet not all product could use it.
I'm agree with this definition:
The word "single" means single object across the application life
cycle, so the scope is at application level.
The static does not have
any Object pointer, so the scope is at App Domain level.
Moreover both should be implemented to be thread-safe.
You can find interesting other differences about: Singleton Pattern Versus Static Class
One notable difference is differed instantiation that comes with Singletons.
With static classes, it gets created by the CLR and we have not control on it.
with singletons, the object gets instantiated on the first instance it's tried to be accessed.
Below are some main differences between static class and singleton:
1.Singleton is a pattern, not a keyword like static. So for creating a static class static keyword is sufficient while in the case of singleton there is a need to write the logic for the singleton.
2.A singleton class must have a private default instance constructor, while a static class cannot contain any instance constructor.
3.A static class is neither instantiated nor extended, while a singleton class can be.
4.A static class is sealed implicitly, but the singleton class must be decorated as sealed explicitly.
5.It is possible for a singleton to implement the interface or inherit from another class, but the static class neither implements the interface nor extends from any other class.
6.We cannot implement the dependency injection with a static class, but DI is possible with the singleton class because it can be interface driven.
The scope of the static class is at the app domain level because it is managed by the CLR, while the scope of the singleton object is across the application lifecycle.
7.A static class cannot have any destructor but a singleton class can define a destructor.
8.The singleton class instance can be passed as a parameter to another method while a static class cannot be because it contains only static members.
Lazy Loading
Support of interfaces, so that separate implementation can be provided
Ability to return derived type (as a combination of lazyloading and interface implementation)
In many cases, these two have no practical difference, especially if the singleton instance never changes or changes very slowly e.g. holding configurations.
I'd say the biggest difference is a singleton is still a normal Java Bean as oppose to a specialized static-only Java class. And because of this, a singleton is accepted in many more situations; it is in fact the default Spring Framework's instantiation strategy. The consumer may or may not know it's a singleton being passed around, it just treat it like a normal Java bean. If requirement changes and a singleton needs to become a prototype instead, as we often see in Spring, it can be done totally seamlessly without a line of code change to the consumer.
Someone else has mentioned earlier that a static class should be purely procedural e.g. java.lang.Math. In my mind, such a class should never be passed around and they should never hold anything other than static final as attributes. For everything else, use a singleton since it's much more flexible and easier to maintain.
We have our DB framework that makes connections to Back end.To Avoid Dirty reads across Multiple users we have used singleton pattern to ensure we have single instance available at any point of time.
In c# a static class cannot implement an interface. When a single instance class needs to implement an interface for a business contracts or IoC purposes, this is where I use the Singleton pattern without a static class
Singleton provides a way to maintain state in stateless scenarios
Hope that helps you..
In an article I wrote I have described my point of view about why the singleton is much better than a static class:
Static class is not actually canonical class – it’s a namespace with functions and variables
Using static class is not a good practice because of breaking object-oriented programming principles
Static class cannot be passed as a parameter for other
Static class is not suitable for “lazy” initialization
Initialization and using of static class is always hard tracked
Implementing thread management is hard
Singleton class provides an object(only one instance) during the application lifeCycle such as java.lang.Runtime
While Static class only provide static methods such as java.lang.Math
Static methods in Java cannot be overridden, but methods defined in Singleton class can be overridden by extending it.
Singleton Class is capable of Inheritance and Polymorphism to extend a base class, implement an interface and capable of providing different implementations. whereas static not.
For eg: java.lang.Runtime,is a Singleton Class in Java, call to getRuntime() method returns the runtime object associated with the current Java application but ensures only one instance per JVM.
a. Serialization - Static members belong to the class and hence can't be serialized.
b. Though we have made the constructor private, static member variables still will be carried to subclass.
c. We can't do lazy initialization as everything will be loaded upon class loading only.
From a client perspective, static behavior is known to the client but Singleton behavior can be completed hidden from a client. Client may never know that there only one single instance he's playing around with again and again.
I read the following and think it makes sense too:
Taking Care of Business
Remember, one of the most important OO rules is that an object is responsible for itself. This means that issues regarding the life cycle of a class should be handled in the class, not delegated to language constructs like static, and so on.
from the book Objected-Oriented Thought Process 4th Ed.
We can create the object of singleton class and pass it to method.
Singleton class doesn't any restriction of inheritance.
We can't dispose the objects of a static class but can singleton class.
I was drawn inspiration from this stackoverflow question
How can one create a Java class instance that is guaranteed to be available only once for the entire JVM process? Every Application that runs on that JVM should then be able to use that singleton instance.
You can as a matter of fact implement such a singleton. The problem that was described to you in the comments is the possibility of a class being loaded by multiple ClassLoaders. Each of these ClassLoaders can then define a class of identical name which would erroneously assume to be unique.
You can however avoid this by implementing an accessor to your singleton which explicitly relies on checking a specific ClassLoader for a class of a given name which again contains your singleton. This way, you can avoid that a singleton instance is provided by two different ClassLoaders and such duplicating the instance you required to be unique throughout the JVM.
For reasons that are explained later, we will split up the Singleton and the SingletonAccessor into two different classes. For the following class, we need to later make sure that we always access it by using a specific ClassLoader:
package pkg;
class Singleton {
static volatile Singleton instance;
}
A convenient ClassLoader for this matter is the system class loader. The system class loader is aware of all classes on the JVM's class path and has per definition the extension and the bootstrap class loaders as its parents. Those two class loaders do not normally know about any classes that are domain-specific such as our Singleton class. This safes us from unwanted surprises. Furthermore, we know that it is accessible and known globally throughout a running instance of the JVM.
For now, let us assume that the Singleton class is on the class path. This way, we can receive the instance by this accessor using reflection:
class SingletonAccessor {
static Object get() {
Class<?> clazz = ClassLoader.getSystemClassLoader()
.findClass("pkg.Singleton");
Field field = clazz.getDeclaredField("instance");
synchronized (clazz) {
Object instance = field.get(null);
if(instance == null) {
instance = clazz.newInstance();
field.set(null, instance);
}
return instance;
}
}
}
By specifying that we explicitly want to load pkg.Singleton from the system class loader, we make sure that we always receive the same instance despite of which class loader loaded our SingletonAccessor. In the above example, we additionally make sure that Singleton is only instantiated once. Alternatively, you could put the instantiation logic into the Singleton class itself and make the unused instances rot in case other Singleton classes are ever loaded.
There is however a big drawback. You miss all means of type-safety as you cannot assume that your code is always run from a ClassLoader which delegates the class loading of Singleton to the system class loader. This is in particularly true for an application run on an application server which often implements child-first semantics for its class loaders and does not ask the system class loader for known types but first tries to load its own types. Note that a runtime type is characterized by two features:
Its fully-qualified name
Its ClassLoader
For this reason, the SingletonAccessor::get method needs to return Object instead of Singleton.
Another drawback is the fact that the Singleton type must be found on the class path for this to work. Otherwise, the system class loader does not know about this type. If you can put the Singleton type onto the class path, you are done here. No problems.
If you cannot make this happen, there is however another way by using for example my code generation library Byte Buddy. Using this library, we can simply define such a type at runtime and inject it into the system class loader:
new ByteBuddy()
.subclass(Object.class)
.name("pkg.Singleton")
.defineField("instance", Object.class, Ownership.STATIC)
.make()
.load(ClassLoader.getSytemClassLoader(),
ClassLoadingStrategy.Default.INJECTION)
You just defined a class pkg.Singleton for the system class loader and the above strategy is applicable again.
Also, you can avoid the type-safety issues by implementing a wrapper type. You can also automatize this with the help of Byte Buddy:
new ByteBuddy()
.subclass(Singleton.class)
.method(any())
.intercept(new Object() {
#RuntimeType
Object intercept(#Origin Method m,
#AllArguments Object[] args) throws Exception {
Object singleton = SingletonAccessor.get();
return singleton.getClass()
.getDeclaredMethod(m.getName(), m.getParameterTypes())
.invoke(singleton, args);
}
})
.make()
.load(Singleton.class.getClassLoader(),
ClassLoadingStrategy.Default.INJECTION)
.getLoaded()
.newInstance();
You just created a delegator which overrides all methods of the Singleton class and delegates their invocation to invocations of the JVM-global singleton instance. Note that we need to reload the reflective methods even though they are signature-identical because we cannot rely on the ClassLoaders of the delegate and the JVM-global classes to be the same.
In practice, you might want to cache the calls to SingletonAccessor.get() and maybe even the reflective method look-ups (which are rather expensive compared to the reflective method invocations). But this need depends highly on your application domain. If you have trouble with your constructor hierarchy, you could also factor out the method signatures into an interface and implement this interface for both the above accessor and your Singleton class.
I am new to Java. One thing confuses me is to why some of the classes need new to instantiate, and why some others do NOT need new to instantiate.
For example, I am looking at log4j, it does not need new.
// get a logger instance named "com.foo"
Logger logger = Logger.getLogger("com.foo");
logger.setLevel(Level.INFO);
Why do some other classes need new? For example, an Employee class:
Employee X = new Employee (John);
X.getwork();
etc etc.
Why we did not say , Logger logger = new Logger(...);? and why were we able to use it even without new, like logger.setLevel(), etc.
The only way to create a new object in Java is with new [1]. However, in some classes, you're not permitted to say new for yourself, you must call a factory method, which might be static (as with your logger example) or not. The author of a class sets this up by making the constructor(s) have access other than public.
Also note that your example may not involve a new object at all. That Logger function might be returning an old object, not a new one.
The following poem by Ogden Nash seems faintly relevant:
This morning I went to the zoo
In order to look at the gnu.
But the old gnu was dead,
and the new gnu, they said,
Was too new a new gnu to view.
[1] Unless you get involved in low-level reflection, or use Object.clone()
In this case, we are dealing with factory methods, as I stated in my comment.
See the relevant API specification on Logger
Retrieve a logger named according to the value of the name parameter. If the named logger already exists, then the existing instance will be returned. Otherwise, a new instance is created.
By default, loggers do not have a set level but inherit it from their neareast ancestor with a set level. This is one of the central features of log4j.
The factory method pattern is a creational design pattern, and, according to Wikipedia, is often useful in the following situations:
The factory pattern can be used when:
The creation of an object precludes its reuse without significant duplication of code.
The creation of an object requires access to information or resources that should not be contained within the composing class.
The lifetime management of the generated objects must be centralized to ensure a consistent behavior within the application.
All three of these are applicable here... who knows what kind of work goes into finding the correct logger? You're not really interested in creating a brand new logger each time you want to use one... instead, your focus is mainly just that -- to use one.
The Creative Commons Wiki also has a relevant article,
Factory methods are sometimes used in place of constructors for any of several reasons:
Some languages (such as Java) do not allow constructors to have useful names
Some languages (such as Java) do not allow constructors to have different names (which may be necessary if you want to use the same method signature for two constructors)
To allow the same instance to be reused instead of recreated each time it is needed (see FlyweightPattern)
I think the third option is probably the most applicable here. Using manual creation of a new Logger, you are unable to adequately share them. Using the getLogger facade enables this to happen transparently.
All in all, the use of factory methods is usually to enable cleaner more straight-forward code without exposing work you don't necessarily care about.
For instance, some classes may prevent you from creating more than one object in the application. It that case you need to call some method for instantiate the class, like the Logger.getLogger(). The getLogger() may have the code like this:
if(uniqueInstance == null) {
uniqueInstance = new Logger();
}
return uniqueInstance;
Where uniqueInstance is an instance of Logger. This is a design pattern called Singleton. In this pattern, you can't instantiate the class because it's constructor is private.
Some other way that you can't instantiate a class is when the class is defined as static.
Classes that have public constructors and aren't static need to be instantiated with the new keyword.
because Logger.getLogger() returns a Logger object. new Logger() calls the constructor which also returns a Logger. This also kind of uses new too, because inside the Logger class is probably something like:
public class Logger {
public static Logger getLogger() {
return new Logger("foo", "bar");
}
}
Well what you are asking is more related to design patterns. The Logger class is following singleton pattern.
Suppose you want that only a single instance of your class gets created accross the application then you can make your constructor private and provide a static method which creates and stores the object of your class when invoked for the first time.
public class SingletonPattern{
private static SingletonPattern instance;
private SingletonPattern(){}
public static synchronized SingletonPattern getInstance(){
if (instance == null){
instance = new SingletonPattern();
}
return instance;
}
}
In this way you can restrict your class to be instantiated only once.
In your example you have to different use cases : the static method that returns an object and the actual constructor call.
The static method is a method that doesn't need to be call on a object, here it's inner mechanism may instantiate an object and return it for futur usage, in this method, there's a call to "new" but the object might be configured, or retrieved from a cache before being return. This is this kind of call
Logger logger = Logger.getLogger("com.foo");
The actual constructor call (which use new) is the normal way to create new object.
You were not technically using the Logger class, but were using a method. You were not technically instantiating the Logger class, nor keeping a reference to it directly as you would with Logger logger = new Logger(). Instead, what you are doing is accessing a method to get back a returned instance. It would be nice to see the class definition. However, more than likely what you have is a static method inside of the class. And the class is more than likely defined with a private constructor. This allows the methods to be accessed without instantiating the class. You can see a good explanation of this, and of static in java here: https://stackoverflow.com/a/1844388/1026459
Some classes cannot be instantiated outside of themselves (e.g. the Math class, these classes have non-public constructors). Of those classes, some provide methods that return instances of the class (e.g. the InetAddress class). These are called factory methods. They are static methods that return instances of the class they're in, so the new keyword need not be used (it is instead used inside of the factory methods). For example:
public class A {
private A() {}
public A createAnA() { return new A(); }
}
Here, createAnA() is the factory method.
I'm trying to track down an issue in our system and the following code worries me. The following occurs in our doPost() method in the primary servlet (names have been changed to protect the guilty):
...
if(Single.getInstance().firstTime()){
doPreperations();
}
normalResponse();
...
The singleton 'Single' looks like this:
private static Single theInstance = new Single();
private Single() {
...load properties...
}
public static Single getInstance() {
return theInstance;
}
With the way this is set to use a static initializer instead of checking for a null theInstance in the getInstance() method, could this get rebuilt over and over again?
PS - We're running WebSphere 6 with the App on Java 1.4
I found this on Sun's site:
Multiple Singletons Simultaneously Loaded by Different Class Loaders
When two class loaders load a class,
you actually have two copies of the
class, and each one can have its own
Singleton instance. That is
particularly relevant in servlets
running in certain servlet engines
(iPlanet for example), where each
servlet by default uses its own class
loader. Two different servlets
accessing a joint Singleton will, in
fact, get two different objects.
Multiple class loaders occur more
commonly than you might think. When
browsers load classes from the network
for use by applets, they use a
separate class loader for each server
address. Similarly, Jini and RMI
systems may use a separate class
loader for the different code bases
from which they download class files.
If your own system uses custom class
loaders, all the same issues may
arise.
If loaded by different class loaders,
two classes with the same name, even
the same package name, are treated as
distinct -- even if, in fact, they are
byte-for-byte the same class. The
different class loaders represent
different namespaces that distinguish
classes (even though the classes'
names are the same), so that the two
MySingleton classes are in fact
distinct. (See "Class Loaders as a
Namespace Mechanism" in Resources.)
Since two Singleton objects belong to
two classes of the same name, it will
appear at first glance that there are
two Singleton objects of the same
class.
Citation.
In addition to the above issue, if firstTime() is not synchronized, you could have threading issues there as well.
No it won't get built over and over again. It's static, so it'll only be constructed once, right when the class is touched for the first time by the Classloader.
Only exception - if you happen to have multiple Classloaders.
(from GeekAndPoke):
As others have mentioned, the static initializer will only be run once per classloader.
One thing I would take a look at is the firstTime() method - why can't the work in doPreparations() be handled within the singleton itself?
Sounds like a nasty set of dependencies.
There is absolutely no difference between using a static initializer and lazy initialization. In fact it's far easier to mess up the lazy initialization, which also enforces synchronization. The JVM guarantees that the static initializer is always run before the class is accessed and it will happen once and only once.
That said JVM does not guarantee that your class will be loaded only once. However even if it is loaded more than once, your web application will still see only the relevant singleton, as it will be loaded either in the web application classloader or its parent. If you have several web application deployed, then firstTime() will be called once for each application.
The most apparent things to check is that firstTime() needs to be synchronized and that the firstTime flag is set before exiting that method.
No, It won't create multiple copies of 'Single'. ( Classloader issue will be visited later )
The implementation you outlined is described as 'Eager Initialization' by in Briant Goetz's book - 'Java Concurrency in Practice'.
public class Single
{
private static Single theInstance = new Single();
private Single()
{
// load properties
}
public static Single getInstance()
{
return theInstance;
}
}
However, the code is not you wanted. Your code is trying to perform lazy-initialization after the instance is created. This requires all the client library to perform 'firstTime()/doPreparation()' before using it. You are going to rely on the client to do right thing which make the code very fragile.
You can modify the code as the following so there won't be any duplicate code.
public class Single
{
private static Single theInstance = new Single();
private Single()
{
// load properties
}
public static Single getInstance()
{
// check for initialization of theInstance
if ( theInstance.firstTime() )
theInstance.doPreparation();
return theInstance;
}
}
Unfortunately, this is a poor implementation of lazy initialization and this will not work in concurrent environment ( like J2EE container ).
There are many articles written about Singleton initialization, specifically on memory model. JSR 133 addressed many weakness in Java memory model in Java 1.5 and 1.6.
With Java 1.5 & 1.6, you have several choices and they are mentioned in the book 'Effective Java' by Joshua Bloch.
Eager Initialziation, like the above [EJ Item 3]
Lazy Initalization Holder Class Idiom [EJ Item 71]
Enum Type [EJ Item 3]
Double Checked Locking with 'volatile' static field [EJ Item 71]
Solution 3 and 4 will only work in Java 1.5 and above. So the best solution would be #2.
Here is the psuedo-implementation.
public class Single
{
private static class SingleHolder
{
public static Single theInstance = new Single();
}
private Single()
{
// load properties
doPreparation();
}
public static Single getInstance()
{
return SingleHolder.theInstance;
}
}
Notice that 'doPreparation()' is inside of the constructor so you are guarantee to get the properly initialized instance. Also, you are piggying back on JVM's lazy class loading and do not need any synchronization 'getInstance()'.
One thing you noticed that static field theInstance is not 'final'. The example on Java Concurrency does not have 'final' but EJ does. Maybe James's can add more color to his answer on 'classloader' and requirement of 'final' to guarantee correctness,
Having said that, there are a side-effect that with using 'static final'. Java compiler is very aggressive when it sees 'static final' and tries to inline it as much as possible. This is mentioned on a blog posting by Jeremy Manson.
Here is a simple example.
file: A.java
public class A
{
final static String word = "Hello World";
}
file: B.java
public class B
{
public static void main(String[] args) {
System.out.println(A.word);
}
}
After you compile both A.java and B.java, you change A.java to following.
file: A.java
public class A
{
final static String word = "Goodbye World";
}
You recompile 'A.java' and rerun B.class. The output you would get is
Hello World
As for the classloader issue, the answer is yes, you can have more than one instance of Singleton in multiple classloaders. You can find more information on wikipedia. There is also a specific article on Websphere.
The only thing I would change about that Singleton implementation (other than not using a Singleton at all) is to make the instance field final. The static field will be initialised once, on class load. Since classes are loaded lazily, you effectively get lazy instantiation for free.
Of course, if it's loaded from separate class loaders you get multiple "singletons", but that's a limitation of every singleton idiom in Java.
EDIT: The firstTime() and doPreparations() bits do look suspect though. Can't they be moved into the constructor of the singleton instance?
No - the static initialization of the instance will only ever be done once. Two things to consider:
This is not thread-safe (the instance is not "published" to main memory)
Your firstTime method is probably called multiple times, unless properly synchronized
In theory it will be built only once. However, this pattern breaks in various application servers, where you can get multiple instances of 'singleton' classes (since they are not thread-safe).
Also, the singleton pattern has been critized a lot. See for instance Singleton I love you, but you're bringing me down
This will get only loaded once when the class is loaded by the classloader.
This example provides a better Singleton implementation however, it's as lazy-loaded as possible and thread-safe.
Moreover, it works in all known versions of Java.
This solution is the most portable across different Java compilers and virtual machines.
public class Single {
private static class SingleHolder {
private static final Single INSTANCE = new Single();
}
private Single() {
...load properties...
}
public static Single getInstance() {
return SingleHolder.INSTANCE;
}
}
The inner class is referenced no earlier (and therefore loaded no earlier by the class loader) than the moment that getInstance() is called. Thus, this solution is thread-safe without requiring special language constructs (i.e. volatile and/or synchronized).
It's not mandatory for the single instance to be final (it's not a good idea at all indeed, because this will avoid you to switch it's behaviour using other patterns).
In the code below you can see how it gets instantiated only once (first time you call the constructor)
package date;
import java.util.Date;
public class USDateFactory implements DateFactory {
private static USDateFactory usdatefactory = null;
private USDateFactory () { }
public static USDateFactory getUsdatefactory() {
if(usdatefactory==null) {
usdatefactory = new USDateFactory();
}
return usdatefactory;
}
public String getTextDate (Date date) {
return null;
}
public NumericalDate getNumericalDate (Date date) {
return null;
}
}