Can I avoid constructor - java

sometimes I reason some basic stuff. This time for instance, can I avoid constructor in java with following,
please consider that I understand that default constructor will be provided by jvm anyway
class TestConstructor {
private String cusName;
private String dbConnectionURL;
private Customer cus;
// avoiding constructor through this init method
public void init(String cusName, String dbConnectionURL, Customer cus) {
this.cus = cus;
this.dbConnectionURL = dbConnectionURL;
this.cusName = cusName;
}
public boolean connectToDatabase(some parameter)
// some code may be to connect to database
return connectionSuccessful;
}
public boolean isCustomerSatisfied() {
// some code to perform some operation
}
// some more methods to do more stuff
and then I can initialize the class and use the class in following way ?
TestConstructor tc = new TestConstructor();
tc.init("John", "db connection string", new Customer(x, y, z));
tc.connectToDatabase(required args go here);
tc.isCustomerSatisfied(required args go here);
the only issue I can think is that you could call init on the same constructor and change values of the object.. which is a security issue and the most major one perhaps.
But is there anything else ?
Pardon me if its a bad question. Just came to my head
Actually I have been preparing for the interview and was thinking what if I was asked such a question - "what constructor does can be achieved this way then why do you need constructor?" following which I started thinking of it
I am surprised that most people are clinging onto 'you used static' .. the code was just the sample to give an idea. The real question was that you could avoid constructor but can you get away with it ? what are the downsides

You can't refer to this in a static method (your init method), since a static method has no access to an instance of the class (unless you pass it such an instance as an argument).
If you want to create an instance with the default constructor and initialize its members with the init method, remove the static keyword.
Other than the issue of the static method, you can certainly use a non-constructor method to initialize the instance. However, what do you gain here? The call to the init method looks the same as a constructor with arguments. The main difference is that, as you mentioned, you can call this init method multiple times.

You appear be trying to create a "factory method".
The following version is incorrect (it won't compile!) because a static method cannot use this. Also, you are not returning an instance.
public static void init(String cusName, String dbConnectionURL, Customer cus) {
this.cus = cus;
this.dbConnectionURL = dbConnectionURL;
this.cusName = cusName;
}
But if you wrote it as follows, it should work:
public static TestConstructor init(String cusName, String dbConnectionURL,
Customer cus) {
TestConstructor res = new TestConstructor();
res.cus = cus;
res.dbConnectionURL = dbConnectionURL;
res.cusName = cusName;
return res;
}
The other way to make that method "work" would be to change the fields to static. But then there will only be one set of variables ... shared by all threads that use the class, etcetera. On the other hand, that might be what you are trying to achieve.
The third possibility is that you intend to use the init method to initialize the object after construction; e.g.
public TestConstructor() { }
public void init(String cusName, String dbConnectionURL, Customer cus) {
this.cus = cus;
this.dbConnectionURL = dbConnectionURL;
this.cusName = cusName;
}
then
TestConstructor tc = new TestConstructor();
tc.init("fred", someURL, someCustomer);
That works ... but I don't see any great advantage in doing that. And the disadvantage is that your TestConstructor objects are constructed in an uninitialized / partially initialized state ... which is bad from the "abstraction" perspective.
The real question was that you could avoid constructor but can you get away with it ? what are the downsides
Yes you can.
One downside is that if you have final instance variables, the can only be initialized in a constructor (or an initializer block which runs before the constructor code). Factory methods and final instance variables that depend on parameters don't mix. The same applies to the init method that is called on a newly constructed instance.
But there are upsides too. For instance the factory method could be an instance method of a factory object, and that allows you to get around some of the issues of using new. (For example, that you can only new a specific class.)

Funnily enough, that's what the JVM does behind the scenes - there's even a method named '' that corresponds to the constructor. However, constructors aren't there to just help out with setting the parameters, they're there so that the system can guarantee that some parameters (or a valid combination of them) has been set.

Related

Why is this final variable null? [duplicate]

I have a Wicket page class that sets the page title depending on the result of an abstract method.
public abstract class BasicPage extends WebPage {
public BasicPage() {
add(new Label("title", getTitle()));
}
protected abstract String getTitle();
}
NetBeans warns me with the message "Overridable method call in constructor", but what should be wrong with it? The only alternative I can imagine is to pass the results of otherwise abstract methods to the super constructor in subclasses. But that could be hard to read with many parameters.
On invoking overridable method from constructors
Simply put, this is wrong because it unnecessarily opens up possibilities to MANY bugs. When the #Override is invoked, the state of the object may be inconsistent and/or incomplete.
A quote from Effective Java 2nd Edition, Item 17: Design and document for inheritance, or else prohibit it:
There are a few more restrictions that a class must obey to allow inheritance. Constructors must not invoke overridable methods, directly or indirectly. If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will be invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected.
Here's an example to illustrate:
public class ConstructorCallsOverride {
public static void main(String[] args) {
abstract class Base {
Base() {
overrideMe();
}
abstract void overrideMe();
}
class Child extends Base {
final int x;
Child(int x) {
this.x = x;
}
#Override
void overrideMe() {
System.out.println(x);
}
}
new Child(42); // prints "0"
}
}
Here, when Base constructor calls overrideMe, Child has not finished initializing the final int x, and the method gets the wrong value. This will almost certainly lead to bugs and errors.
Related questions
Calling an Overridden Method from a Parent-Class Constructor
State of Derived class object when Base class constructor calls overridden method in Java
Using abstract init() function in abstract class’s constructor
See also
FindBugs - Uninitialized read of field method called from constructor of superclass
On object construction with many parameters
Constructors with many parameters can lead to poor readability, and better alternatives exist.
Here's a quote from Effective Java 2nd Edition, Item 2: Consider a builder pattern when faced with many constructor parameters:
Traditionally, programmers have used the telescoping constructor pattern, in which you provide a constructor with only the required parameters, another with a single optional parameters, a third with two optional parameters, and so on...
The telescoping constructor pattern is essentially something like this:
public class Telescope {
final String name;
final int levels;
final boolean isAdjustable;
public Telescope(String name) {
this(name, 5);
}
public Telescope(String name, int levels) {
this(name, levels, false);
}
public Telescope(String name, int levels, boolean isAdjustable) {
this.name = name;
this.levels = levels;
this.isAdjustable = isAdjustable;
}
}
And now you can do any of the following:
new Telescope("X/1999");
new Telescope("X/1999", 13);
new Telescope("X/1999", 13, true);
You can't, however, currently set only the name and isAdjustable, and leaving levels at default. You can provide more constructor overloads, but obviously the number would explode as the number of parameters grow, and you may even have multiple boolean and int arguments, which would really make a mess out of things.
As you can see, this isn't a pleasant pattern to write, and even less pleasant to use (What does "true" mean here? What's 13?).
Bloch recommends using a builder pattern, which would allow you to write something like this instead:
Telescope telly = new Telescope.Builder("X/1999").setAdjustable(true).build();
Note that now the parameters are named, and you can set them in any order you want, and you can skip the ones that you want to keep at default values. This is certainly much better than telescoping constructors, especially when there's a huge number of parameters that belong to many of the same types.
See also
Wikipedia/Builder pattern
Effective Java 2nd Edition, Item 2: Consider a builder pattern when faced with many constructor parameters (excerpt online)
Related questions
When would you use the Builder Pattern?
Is this a well known design pattern? What is its name?
Here's an example which helps to understand this:
public class Main {
static abstract class A {
abstract void foo();
A() {
System.out.println("Constructing A");
foo();
}
}
static class C extends A {
C() {
System.out.println("Constructing C");
}
void foo() {
System.out.println("Using C");
}
}
public static void main(String[] args) {
C c = new C();
}
}
If you run this code, you get the following output:
Constructing A
Using C
Constructing C
You see? foo() makes use of C before C's constructor has been run. If foo() requires C to have a defined state (i.e. the constructor has finished), then it will encounter an undefined state in C and things might break. And since you can't know in A what the overwritten foo() expects, you get a warning.
Invoking an overridable method in the constructor allows subclasses to subvert the code, so you can't guarantee that it works anymore. That's why you get a warning.
In your example, what happens if a subclass overrides getTitle() and returns null ?
To "fix" this, you can use a factory method instead of a constructor, it's a common pattern of objects instanciation.
Here is an example that reveals the logical problems that can occur when calling an overridable method in the super constructor.
class A {
protected int minWeeklySalary;
protected int maxWeeklySalary;
protected static final int MIN = 1000;
protected static final int MAX = 2000;
public A() {
setSalaryRange();
}
protected void setSalaryRange() {
throw new RuntimeException("not implemented");
}
public void pr() {
System.out.println("minWeeklySalary: " + minWeeklySalary);
System.out.println("maxWeeklySalary: " + maxWeeklySalary);
}
}
class B extends A {
private int factor = 1;
public B(int _factor) {
this.factor = _factor;
}
#Override
protected void setSalaryRange() {
this.minWeeklySalary = MIN * this.factor;
this.maxWeeklySalary = MAX * this.factor;
}
}
public static void main(String[] args) {
B b = new B(2);
b.pr();
}
The result would actually be:
minWeeklySalary: 0
maxWeeklySalary: 0
This is because the constructor of class B first calls the constructor of class A, where the overridable method inside B gets executed. But inside the method we are using the instance variable factor which has not yet been initialized (because the constructor of A has not yet finished), thus factor is 0 and not 1 and definitely not 2 (the thing that the programmer might think it will be). Imagine how hard would be to track an error if the calculation logic was ten times more twisted.
I hope that would help someone.
If you call methods in your constructor that subclasses override, it means you are less likely to be referencing variables that don’t exist yet if you divide your initialization logically between the constructor and the method.
Have a look on this sample link http://www.javapractices.com/topic/TopicAction.do?Id=215
I certainly agree that there are cases where it is better not to call some methods from a constructor.
Making them private takes away all doubt: "You shall not pass".
However, what if you DO want to keep things open.
It's not just the access modifier that is the real problem, as I tried to explain here. To be completely honest, private is a clear showstopper where protected usually will still allow a (harmful) workaround.
A more general advice:
don't start threads from your constructor
don't read files from your constructor
don't call APIs or services from your constructor
don't load data from a database from your constructor
don't parse json or xml documents from your constructor
Don't do so (in)directly from your constructor. That includes doing any of these actions from a private/protected function which is called by the constructor.
Calling an start() method from your constructor could certainly be a red flag.
Instead, you should provide a public init(), start() or connect() method. And leave the responsibility to the consumer.
Simply put, you want to separate the moment of "preparation" from the "ignition".
if a constructor can be extended then it shouldn't self-ignite.
If it self-ignites then it risks being launched before being fully constructed.
After all, some day more preparation could be added in the constructor of a subclass. And you don't have any control over the order of execution of the constructor of a super class.
PS: consider implementing the Closeable interface along with it.
In the specific case of Wicket: This is the very reason why I asked the Wicket
devs to add support for an explicit two phase component initialization process in the framework's lifecycle of constructing a component i.e.
Construction - via constructor
Initialization - via onInitilize (after construction when virtual methods work!)
There was quite an active debate about whether it was necessary or not (it fully is necessary IMHO) as this link demonstrates http://apache-wicket.1842946.n4.nabble.com/VOTE-WICKET-3218-Component-onInitialize-is-broken-for-Pages-td3341090i20.html)
The good news is that the excellent devs at Wicket did end up introducing two phase initialization (to make the most aweseome Java UI framework even more awesome!) so with Wicket you can do all your post construction initialization in the onInitialize method that is called by the framework automatically if you override it - at this point in the lifecycle of your component its constructor has completed its work so virtual methods work as expected.
I guess for Wicket it's better to call add method in the onInitialize() (see components lifecycle) :
public abstract class BasicPage extends WebPage {
public BasicPage() {
}
#Override
public void onInitialize() {
add(new Label("title", getTitle()));
}
protected abstract String getTitle();
}

Why is subclass field initialized to its default value within super constructor? [duplicate]

I ran into an interesting problem yesterday and while the fix was quite simple, I'm still a bit fuzzy on the "why" of it.
I have a class that has a private member variable that is assigned when it is instantiated, however if it is used in an abstract function that is called by the super class's constructor, the variable does not have a value. The solution to the problem was quite simple, I simply had to declare the variable as static and it was assigned correctly. Some code to illustrate the problem:
class Foo extends BaseClass
{
private final String bar = "fooBar!";
public Foo()
{
super();
}
#Override
public void initialize()
{
System.out.println(bar);
}
}
And the base class:
abstract class BaseClass
{
public BaseClass()
{
initialize();
}
public abstract void initialize();
}
In this example, when we call new Foo(); it will output (null) instead of the expected fooBar!
Since we're instantiated an object of type Foo, should its members not be allocated and assigned prior to calling its (and consequently its super class's) constructor? Is this specified somewhere in the Java language or is it JVM specific?
Thanks for any insight!
The assignment of bar = "fooBar!"; is inlined into the constructor during compile time.
The superclass constructor runs before the subclass constructor, hence it would only be natural that the statement is executed afterwards.
Generally though, it's bad practice to call overridable methods from a constructor.
It is as defined by the Java Language Specification. Changing it to static will almost never be and acceptable solution in real world situation.
See JLS 4.12.5 Initial Values of Variablesand JLS 8.3.2 Initialization of Fields
Overall, it is bad practice to call a non-final method from a constructor. the reason being that it could (and if the method is abstract then definitely does) call method in the class that has not yet been initialized: When new Foo() is executed, the BaseClass initializer (constructor) gets called before the Foo constructor, so Foo.initialize is essentially working on an Object that has not been fully constructed yet.
There's just one thing I would like to add to the accepted answer, because I don't entirely agree with his conclusion.
We've all done this.
class Engine {
public Engine() {
init();
}
void init() {
lockDoors();
releasePressure();
tightenSeatbelts();
launchRocket();
}
...
}
Now the question is, which access modifier should we add to our init() function. Should it be private or protected.
make it private <-- keeps subclasses out
make it protected <-- allows subclasses in
Before you make a choice
Now first of all, you should realize that (almost) all code in the Engine class can be replaced by a subclass.
code in a public function, can easily be overridden
code in a protected function, can easily be overridden
code in a private function, can be replaced by overriding all methods that call it.
Well, there is just one exception:
you can never modify the code of a constructor
you can never avoid a private method being called from the constructor of a super class.
(and of course, you cannot replace a final method)
Protected init() - the wrong way
Let's say the init() method is protected there is indeed a pitfall. It is tempting to override it to add features as follows. That would indeed be a mistake.
class SubEngine extends Engine {
int screws = 5;
void init() {
tightenScrews();
super.init();
}
void tightenScrews() {
// this won't print 5, but it will print 0.
System.out.println("tightening " + screws + " screws");
}
}
Protected init() - the right way
So, basically, you should just disable the parents code and postpone execution to your own constructor instead.
class SubEngine extends Engine {
int screws = 5;
public SubEngine() {
initSubEngine();
}
void init() {
// disable parent code
}
void initSubEngine() {
tightenScrews();
super.init();
}
void tightenScrews() {
// this will print 5 as expected
System.out.println("tightening " + screws + " screws");
}
}
Private init() - you may need a phonecall
Now, what if the init() method is private ?
Like mentioned above, there is no way to disable the code of a parent constructor. And if init() is private you simply cannot disable it.
You'll end up copying the entire Engine class, perhaps just to add 1 line of code.
And that may not be the end of it. Even after copying your class, your copied object won't be an Engine meaning that you won't be able to use your EngineUtil#inspectEngine(Engine engine) function.
Perhaps somebody knew this in advance and made an IEngine interface. Then you can get away with it.
In practice it means you'll have to take your phone, and call to that other department that made the Engine class, and ask them to change their code a little to take away some restrictions.
Intelligent design
There is another way. Constructors are for setting variables. They shouldn't activate anything. Everytime you see a class creating a new Thread from their constructor (or through a private method) that should be a red flag.
class Engine {
public Engine() {
}
public void init() {
lockDoors();
releasePressure();
tightenSeatbelts();
launchRocket();
}
// and you probably also want one of these
public void shutdown() { ... }
...
}
Intention
Of course, your intention may very well be not to open up your code. Perhaps you really don't want to allow others to extend your classes. There certainly can be cases where you want to lock people out.
Be aware that it will also make it harder to write tests for your code.
Anyway that's a different scenario.

Constructor invoke overridable method in Java [duplicate]

I have a Wicket page class that sets the page title depending on the result of an abstract method.
public abstract class BasicPage extends WebPage {
public BasicPage() {
add(new Label("title", getTitle()));
}
protected abstract String getTitle();
}
NetBeans warns me with the message "Overridable method call in constructor", but what should be wrong with it? The only alternative I can imagine is to pass the results of otherwise abstract methods to the super constructor in subclasses. But that could be hard to read with many parameters.
On invoking overridable method from constructors
Simply put, this is wrong because it unnecessarily opens up possibilities to MANY bugs. When the #Override is invoked, the state of the object may be inconsistent and/or incomplete.
A quote from Effective Java 2nd Edition, Item 17: Design and document for inheritance, or else prohibit it:
There are a few more restrictions that a class must obey to allow inheritance. Constructors must not invoke overridable methods, directly or indirectly. If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will be invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected.
Here's an example to illustrate:
public class ConstructorCallsOverride {
public static void main(String[] args) {
abstract class Base {
Base() {
overrideMe();
}
abstract void overrideMe();
}
class Child extends Base {
final int x;
Child(int x) {
this.x = x;
}
#Override
void overrideMe() {
System.out.println(x);
}
}
new Child(42); // prints "0"
}
}
Here, when Base constructor calls overrideMe, Child has not finished initializing the final int x, and the method gets the wrong value. This will almost certainly lead to bugs and errors.
Related questions
Calling an Overridden Method from a Parent-Class Constructor
State of Derived class object when Base class constructor calls overridden method in Java
Using abstract init() function in abstract class’s constructor
See also
FindBugs - Uninitialized read of field method called from constructor of superclass
On object construction with many parameters
Constructors with many parameters can lead to poor readability, and better alternatives exist.
Here's a quote from Effective Java 2nd Edition, Item 2: Consider a builder pattern when faced with many constructor parameters:
Traditionally, programmers have used the telescoping constructor pattern, in which you provide a constructor with only the required parameters, another with a single optional parameters, a third with two optional parameters, and so on...
The telescoping constructor pattern is essentially something like this:
public class Telescope {
final String name;
final int levels;
final boolean isAdjustable;
public Telescope(String name) {
this(name, 5);
}
public Telescope(String name, int levels) {
this(name, levels, false);
}
public Telescope(String name, int levels, boolean isAdjustable) {
this.name = name;
this.levels = levels;
this.isAdjustable = isAdjustable;
}
}
And now you can do any of the following:
new Telescope("X/1999");
new Telescope("X/1999", 13);
new Telescope("X/1999", 13, true);
You can't, however, currently set only the name and isAdjustable, and leaving levels at default. You can provide more constructor overloads, but obviously the number would explode as the number of parameters grow, and you may even have multiple boolean and int arguments, which would really make a mess out of things.
As you can see, this isn't a pleasant pattern to write, and even less pleasant to use (What does "true" mean here? What's 13?).
Bloch recommends using a builder pattern, which would allow you to write something like this instead:
Telescope telly = new Telescope.Builder("X/1999").setAdjustable(true).build();
Note that now the parameters are named, and you can set them in any order you want, and you can skip the ones that you want to keep at default values. This is certainly much better than telescoping constructors, especially when there's a huge number of parameters that belong to many of the same types.
See also
Wikipedia/Builder pattern
Effective Java 2nd Edition, Item 2: Consider a builder pattern when faced with many constructor parameters (excerpt online)
Related questions
When would you use the Builder Pattern?
Is this a well known design pattern? What is its name?
Here's an example which helps to understand this:
public class Main {
static abstract class A {
abstract void foo();
A() {
System.out.println("Constructing A");
foo();
}
}
static class C extends A {
C() {
System.out.println("Constructing C");
}
void foo() {
System.out.println("Using C");
}
}
public static void main(String[] args) {
C c = new C();
}
}
If you run this code, you get the following output:
Constructing A
Using C
Constructing C
You see? foo() makes use of C before C's constructor has been run. If foo() requires C to have a defined state (i.e. the constructor has finished), then it will encounter an undefined state in C and things might break. And since you can't know in A what the overwritten foo() expects, you get a warning.
Invoking an overridable method in the constructor allows subclasses to subvert the code, so you can't guarantee that it works anymore. That's why you get a warning.
In your example, what happens if a subclass overrides getTitle() and returns null ?
To "fix" this, you can use a factory method instead of a constructor, it's a common pattern of objects instanciation.
Here is an example that reveals the logical problems that can occur when calling an overridable method in the super constructor.
class A {
protected int minWeeklySalary;
protected int maxWeeklySalary;
protected static final int MIN = 1000;
protected static final int MAX = 2000;
public A() {
setSalaryRange();
}
protected void setSalaryRange() {
throw new RuntimeException("not implemented");
}
public void pr() {
System.out.println("minWeeklySalary: " + minWeeklySalary);
System.out.println("maxWeeklySalary: " + maxWeeklySalary);
}
}
class B extends A {
private int factor = 1;
public B(int _factor) {
this.factor = _factor;
}
#Override
protected void setSalaryRange() {
this.minWeeklySalary = MIN * this.factor;
this.maxWeeklySalary = MAX * this.factor;
}
}
public static void main(String[] args) {
B b = new B(2);
b.pr();
}
The result would actually be:
minWeeklySalary: 0
maxWeeklySalary: 0
This is because the constructor of class B first calls the constructor of class A, where the overridable method inside B gets executed. But inside the method we are using the instance variable factor which has not yet been initialized (because the constructor of A has not yet finished), thus factor is 0 and not 1 and definitely not 2 (the thing that the programmer might think it will be). Imagine how hard would be to track an error if the calculation logic was ten times more twisted.
I hope that would help someone.
If you call methods in your constructor that subclasses override, it means you are less likely to be referencing variables that don’t exist yet if you divide your initialization logically between the constructor and the method.
Have a look on this sample link http://www.javapractices.com/topic/TopicAction.do?Id=215
I certainly agree that there are cases where it is better not to call some methods from a constructor.
Making them private takes away all doubt: "You shall not pass".
However, what if you DO want to keep things open.
It's not just the access modifier that is the real problem, as I tried to explain here. To be completely honest, private is a clear showstopper where protected usually will still allow a (harmful) workaround.
A more general advice:
don't start threads from your constructor
don't read files from your constructor
don't call APIs or services from your constructor
don't load data from a database from your constructor
don't parse json or xml documents from your constructor
Don't do so (in)directly from your constructor. That includes doing any of these actions from a private/protected function which is called by the constructor.
Calling an start() method from your constructor could certainly be a red flag.
Instead, you should provide a public init(), start() or connect() method. And leave the responsibility to the consumer.
Simply put, you want to separate the moment of "preparation" from the "ignition".
if a constructor can be extended then it shouldn't self-ignite.
If it self-ignites then it risks being launched before being fully constructed.
After all, some day more preparation could be added in the constructor of a subclass. And you don't have any control over the order of execution of the constructor of a super class.
PS: consider implementing the Closeable interface along with it.
In the specific case of Wicket: This is the very reason why I asked the Wicket
devs to add support for an explicit two phase component initialization process in the framework's lifecycle of constructing a component i.e.
Construction - via constructor
Initialization - via onInitilize (after construction when virtual methods work!)
There was quite an active debate about whether it was necessary or not (it fully is necessary IMHO) as this link demonstrates http://apache-wicket.1842946.n4.nabble.com/VOTE-WICKET-3218-Component-onInitialize-is-broken-for-Pages-td3341090i20.html)
The good news is that the excellent devs at Wicket did end up introducing two phase initialization (to make the most aweseome Java UI framework even more awesome!) so with Wicket you can do all your post construction initialization in the onInitialize method that is called by the framework automatically if you override it - at this point in the lifecycle of your component its constructor has completed its work so virtual methods work as expected.
I guess for Wicket it's better to call add method in the onInitialize() (see components lifecycle) :
public abstract class BasicPage extends WebPage {
public BasicPage() {
}
#Override
public void onInitialize() {
add(new Label("title", getTitle()));
}
protected abstract String getTitle();
}

singleton public static final

I've been wondering about singletons in Java. By convention, a singleton is set up something like this:
private static MyClass instance = null;
public static MyClass getInstance(){
if (instance == null){
instance = new MyClass();
}
return instance;
}
private MyClass(){}
Recently I've switched to using the following:
public static final MyClass instance = new MyClass();
private MyClass(){}
This is a lot shorter, faster as there's no null-check, and typing MyClass.instance feels nicer to me than typing MyClass.getInstance(). Is there any reason why the second is not the mainstream way to do this?
The first version creates the instance the first time it is actually needed, while the second (the shorter) runs the constructor as soon as the class is initialized
A class or interface type T will be initialized immediately before the
first occurrence of any one of the following:
T is a class and an instance of T is created.
T is a class and a static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the field is not a constant
variable (§4.12.4).
T is a top level class (§7.6), and an assert statement (§14.10)
lexically nested within T (§8.1.3) is executed. [...]
Invocation of certain reflective methods in class Class and in
package java.lang.reflect also causes class or interface initialization.
The initialization upon first usage is a performance improvement that may speed up the startup of the application if the code in the constructor makes expensive operations. On the other hand, the second version is straightforward to read and is automatically thread-safe.
Anyway, the state of the art is not creating singleton in either ways: for a bunch of KB you can get dependency injection libraries that make it working for you, and also handle more complex scenarios (for example look at Spring and AOP-backed injection).
Note: the first version is not thread safe in the pasted snippet
The way you have first described is known as lazy instantiation, i.e the object will only be created when it is first called. This method is not thread-safe as it is possible for a second thread to create a second instance.
If you read the following book:
Effective Java by Joshua Bloch
He explains that the best implementation of the singleton pattern is through the use of an Enum :
public enum Singleton {
INSTANCE;
public void doSomething() {
...
}
}
Then you would call your singleton through the Enum as follows:
public class Test {
public void test(){
Singleton.INSTANCE.doSomething();
}
}
This fits nicely with what you are saying in terms of it looks nicer and shorter to write but also guarantees there can never be a second instance.
I can think of two reasons:
The first is Encapsulation: you might have second thoughts about how and when your singleton is initialized, after your class has been exposed to client code. And an initialization method gives you more freedom as to changing your strategy later on. For example you might change your mind and decide to use two different constructors instead of one, according to another static variable's value at runtime. With your solution you're bound to using just one constructor at the time your class is loaded into memory, whereas with getInstance() you can change the initialization logic without affecting the interface to the client code.
The second is Lazy Initialization : with the conventional singleton implementation the MyClass object is loaded into memory only when needed by the client code for the first time. And if the client code doesn't need it at all, you save on the memory allocated by your application. Note that whether your singleton is needed or not might not be certain until the program runs. For example it might depend on the user interaction with the program.
However the Lazy Initialization is not something you might necessarily want. For example if you're programming an interactive system and the initialization of your singleton is time consuming, it might actually be better to initialize it when the program is loading rather than when the user is already interacting with it, cause the latter might cause a latency in your system response the first time getInstance() is called. But in this case you can just have your instance initialized with the public method as in:
private static MyClass instance = getInstance();
The best way to synchronize the threads is using Double Checked (to ensure that only one thread will enter the synchronized block at a time and to avoid obtaining the lock every time the code is executed).
public class DoubleCheckLocking {
public static class SearchBox {
private static volatile SearchBox searchBox;
// private attribute of this class
private String searchWord = "";
private String[] list = new String[]{"Stack", "Overflow"};
// private constructor
private SearchBox() {}
// static method to get instance
public static SearchBox getInstance() {
if (searchBox == null) { // first time lock
synchronized (SearchBox.class) {
if (searchBox == null) { // second time lock
searchBox = new SearchBox();
}
}
}
return searchBox;
}
}
Reflection: Reflection can be caused to destroy singleton
property of singleton class, as shown in following example:
// Java code to explain effect of Reflection
import java.lang.reflect.Constructor;
// Singleton class
class Singleton
{
// public instance initialized when loading the class
public static Singleton instance = new Singleton();
private Singleton()
{
// private constructor
}
}
public class GFG
{
public static void main(String[] args)
{
Singleton instance1 = Singleton.instance;
Singleton instance2 = null;
try
{
Constructor[] constructors =
Singleton.class.getDeclaredConstructors();
for (Constructor constructor : constructors)
{
// Below code will destroy the singleton pattern
constructor.setAccessible(true);
instance2 = (Singleton) constructor.newInstance();
break;
}
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println("instance1.hashCode():- "
+ instance1.hashCode()); //366712642
System.out.println("instance2.hashCode():- "
+ instance2.hashCode()); //1829164700
}
}

Why are member objects initialized after the super class's constructor?

I ran into an interesting problem yesterday and while the fix was quite simple, I'm still a bit fuzzy on the "why" of it.
I have a class that has a private member variable that is assigned when it is instantiated, however if it is used in an abstract function that is called by the super class's constructor, the variable does not have a value. The solution to the problem was quite simple, I simply had to declare the variable as static and it was assigned correctly. Some code to illustrate the problem:
class Foo extends BaseClass
{
private final String bar = "fooBar!";
public Foo()
{
super();
}
#Override
public void initialize()
{
System.out.println(bar);
}
}
And the base class:
abstract class BaseClass
{
public BaseClass()
{
initialize();
}
public abstract void initialize();
}
In this example, when we call new Foo(); it will output (null) instead of the expected fooBar!
Since we're instantiated an object of type Foo, should its members not be allocated and assigned prior to calling its (and consequently its super class's) constructor? Is this specified somewhere in the Java language or is it JVM specific?
Thanks for any insight!
The assignment of bar = "fooBar!"; is inlined into the constructor during compile time.
The superclass constructor runs before the subclass constructor, hence it would only be natural that the statement is executed afterwards.
Generally though, it's bad practice to call overridable methods from a constructor.
It is as defined by the Java Language Specification. Changing it to static will almost never be and acceptable solution in real world situation.
See JLS 4.12.5 Initial Values of Variablesand JLS 8.3.2 Initialization of Fields
Overall, it is bad practice to call a non-final method from a constructor. the reason being that it could (and if the method is abstract then definitely does) call method in the class that has not yet been initialized: When new Foo() is executed, the BaseClass initializer (constructor) gets called before the Foo constructor, so Foo.initialize is essentially working on an Object that has not been fully constructed yet.
There's just one thing I would like to add to the accepted answer, because I don't entirely agree with his conclusion.
We've all done this.
class Engine {
public Engine() {
init();
}
void init() {
lockDoors();
releasePressure();
tightenSeatbelts();
launchRocket();
}
...
}
Now the question is, which access modifier should we add to our init() function. Should it be private or protected.
make it private <-- keeps subclasses out
make it protected <-- allows subclasses in
Before you make a choice
Now first of all, you should realize that (almost) all code in the Engine class can be replaced by a subclass.
code in a public function, can easily be overridden
code in a protected function, can easily be overridden
code in a private function, can be replaced by overriding all methods that call it.
Well, there is just one exception:
you can never modify the code of a constructor
you can never avoid a private method being called from the constructor of a super class.
(and of course, you cannot replace a final method)
Protected init() - the wrong way
Let's say the init() method is protected there is indeed a pitfall. It is tempting to override it to add features as follows. That would indeed be a mistake.
class SubEngine extends Engine {
int screws = 5;
void init() {
tightenScrews();
super.init();
}
void tightenScrews() {
// this won't print 5, but it will print 0.
System.out.println("tightening " + screws + " screws");
}
}
Protected init() - the right way
So, basically, you should just disable the parents code and postpone execution to your own constructor instead.
class SubEngine extends Engine {
int screws = 5;
public SubEngine() {
initSubEngine();
}
void init() {
// disable parent code
}
void initSubEngine() {
tightenScrews();
super.init();
}
void tightenScrews() {
// this will print 5 as expected
System.out.println("tightening " + screws + " screws");
}
}
Private init() - you may need a phonecall
Now, what if the init() method is private ?
Like mentioned above, there is no way to disable the code of a parent constructor. And if init() is private you simply cannot disable it.
You'll end up copying the entire Engine class, perhaps just to add 1 line of code.
And that may not be the end of it. Even after copying your class, your copied object won't be an Engine meaning that you won't be able to use your EngineUtil#inspectEngine(Engine engine) function.
Perhaps somebody knew this in advance and made an IEngine interface. Then you can get away with it.
In practice it means you'll have to take your phone, and call to that other department that made the Engine class, and ask them to change their code a little to take away some restrictions.
Intelligent design
There is another way. Constructors are for setting variables. They shouldn't activate anything. Everytime you see a class creating a new Thread from their constructor (or through a private method) that should be a red flag.
class Engine {
public Engine() {
}
public void init() {
lockDoors();
releasePressure();
tightenSeatbelts();
launchRocket();
}
// and you probably also want one of these
public void shutdown() { ... }
...
}
Intention
Of course, your intention may very well be not to open up your code. Perhaps you really don't want to allow others to extend your classes. There certainly can be cases where you want to lock people out.
Be aware that it will also make it harder to write tests for your code.
Anyway that's a different scenario.

Categories