I was looking at other questions on SO, but I didn't really see an explanation for my question. I read that calling a constructor from another constructor (using the this keyword) was valid, but I didn't understand why it was valid.
Previously, I thought that only one constructor could act per object. Constructor chaining seems to break this logic, in that while calling one constructor, it runs another in conjunction to the original, targeted constructor. Why does constructor chaining work?
We chain (call) one constructor from other within the same class so that we can avoid code duplication. Without chaining every constructor, we end up repeating business details and that leads to code duplication and hard to maintain the code as well.
Imagine you are creating a Bus.
public class Bus {
int noOfSeats;
String busColor;
public Bus() {
this(40); //// Using another constructor and proceeding with default values..
}
public Bus(int seats) {
this(seats,"red"); // Using another constructor and proceeding..
}
public Bus(int seats, String color) {
this.noOfSeats = seats;
this.busColor = color;
}
}
And the person using this class can use only constructor at a time, where as you are using chaining internally. Imagine that you have a method which initializes things with default values and calling it in the constructor. There's nothing wrong in that, right?
Just to clarify, the person who is creating the object is calling only one constructor. The invoked constructor calls others which is internal to that class.
Delegated constructors reduce the amount of duplicate code, since you can exploit the functionality set up in one constructor by calling it from another one.
Until this feature was designed into languages, we had to rely on "initialisation"-type functions that were called from constructors. That was a pain for two reasons (i) you could never guarantee that the functions were only called from constructors, and (ii) calling class methods from constructors is always a design "smell".
It allows to clarify the logic and reduce the code.
Is nesting constructors (or factory methods) good, or should each do all init work
It's reasonable to chain constructors together, the version with fewer parameters calls the version with more parameters. It makes very clear what's happening, and all the real "logic" (beyond the default values) is in a single place. For example:
public class Foo {
private static final int DEFAULT_X =10;
private static final int DEFAULT_Y =20;
private int x;
private int y;
private int precomputedValue;
public Foo(int x, int y) {
this.x = x;
this.y = y;
precomputedValue = x * y;
}
public Foo(int x) {
this(x, DEFAULT_Y);
}
public Foo() {
this(DEFAULT_X, DEFAULT_Y)
}
}
Not a Java dev here, but in Python this is also allowed and pretty much normal.
Whenever you inherit a class, you might want to call the parent class's constructor prior adding your own stuff-and-recipes.
This allows you to benefit the parent class's construction features. Whenever you do not know exactly what the parent class does you most of the time always call it first in order to avoid the parent's class features and methods being broken.
The fact that the confusion originates from every instance should call one ctor is absolutely right. The constructor chained another is used to avoid code duplication and simplicity because copying same code is really overhead. Sometimes maybe we need two constructors, first one just takes two parameters the other one takes three parameters. But, three parameters-ctor uses same variables of two parameters-ctor. Do you prefer copy-paste same assignmets or merely call the other ctor by this?
As a supplement to the other answers, I would like to share another use for calling a constructor from a constructor that I use often.
Another strategy of constructor chaining that I find useful is providing default implementations / auto-injection for Interfaces.
public class Foo {
private readonly ILogger _logger;
//Default implementation for most cases
public Foo() : this(new DefaultLoggerImplementation()) {}
//DI Constructor that allows for different implementations of ILogger
//(Or Mocks in testing)
public Foo(ILogger logger)
{
_logger = logger;
}
public void Log(string message)
{
_logger.log(message);
}
}
This way if you have a default implementation for an interface it is auto injected via new Foo()
If you have a case with different ILogger behavior it is easily injectable, this also promotes the ability to Mock the interface in your unit testing framework.
Related
What are the advantages/disadvantages of init method over a constructor in java? They both have the same purpose. How to choose between them?
public class A {
private int x;
public A(int x){
this.x = x;
}
public void init(int x){
this.x = x;
}
}
Here we can use either constructor or init method.
You are wrong. They do not have the same purpose.
A constructor is always required when you want to create a new object using the new() operator.
A init method is something that might make sense in certain contexts, for example servlet stuff (see here for further reading regarding this aspect).
And please note: in your example, one could your init method more as a setter - as it is simply setting the corresponding field.
Coming from there:
first of all, you think about the constructors that you want to put into you class (by asking: which information is required to create a new instance of the class)
if there is special need, then consider adding setters for specific fields - or as layed out above, it might be required to provide an init() method (in case where object creation and initializiation can not happen at the same point of time)
Constructor is not a regular method. It's special in a sense that it gets always called when you invoke new A(). If you don't provide a constructor, Java creates one automatically. As a consequence, constructors do not have a return (i.e. they return this) and always have the same name as the class.
On the other hand, init is a regular method, which you can call - or not. There is no universally accepted consensus for any kind of "init" methods. So it depends on what you want to do. If you want to ensure that the new calls your logic, use constructor. If you want to have your own stuff, use plain methods. You can mix and match, just be sure to write a good documentation about how your class is supposed to be used.
I have recently found out that no argument constructor and multiple argument constructor cannnot call each other in turns. What is the underlying reason of this limitation? Some might say that constructors are where resources are initialised. So they must not be called recursively. I want to know if this is the only reason or not. Functions/methods/procedures can be called recursively. Why not constructors?
The answer lies in the fact that the call to another constructor is the first line of any constructor and hence your if condition to break out of recursion will never be executed and hence stack overflow.
The main purpose of the constructor is to initialize all the global variables described in a particular class.
For Example:
public class Addition(){
int value1;
int value2;
public Addition(){ // default constructor
a=10;
b=10;
}
public Addition(int a, int b){
this(); // constructors having parameters , overloaded constructor
value1=a;
value2=b;
}
}
public class Main(){
public static void main(){
Addition addition = new Addition(); //or
Addition addition = new Addition(15,15);
}
}
Here, if you want to make instance of the class you can either make instance by calling default constructor or by calling constructor having parameters. So the constructors are overloaded and not overridden. If you want to call another constructor, that can only be done be putting either this() or super() in the first line of the constructor. But this is not prefferable.
Constructors are not intended to be called explicitly outside object initialization, because it's restricted in most (I guess all) languages. Instead, you can create an additional protected Init(...) member function and call it inside the constructor.
Your statement that constructor cannot call other constructors are not true for every programming languages. At least I know Java can do this, while C++ cannot. But you could easily overcome this limitation by writing a private __init function and let all your constructors call it.
In all languages you've listed objects contain finite (and normally short) set of properties. Each property could contain recursive structure (i.e. list), but it still represented by a single property in the object.
I don't see need to recursively call constructors. It feels like a strange use recursion to initialize several well know properties.
As you've said you can call constructors in non-recursive way to share code in some languages you've mentioned.
C#: Using Constructors
public Employee(int weeklySalary, int numberOfWeeks)
: this(weeklySalary * numberOfWeeks)
{
}
My concern in the code below is that the param to constructor is not actually directly mapped to the class's instance fields. The instance fields derive value from the parameter and for which I'm using the initalize method. Further, I do some stuff so that the object created can be used directly in the code that follows e.g. calling drawBoundaries(). I feel it's doing what is meant by creating(initializing) a Canvas in an abstract sense.
Is my constructor doing too much? If I add methods to call the stuff in constructor explicitly from outside, that'll be wrong. Please let me know your views.
public class Canvas {
private int numberOfRows;
private int numberOfColumns;
private final List<Cell> listOfCells = new LinkedList<Cell>();
public Canvas(ParsedCells seedPatternCells) {
initalizeCanvas(seedPatternCells);
}
private void initalizeCanvas(ParsedCells seedPatternCells) {
setNumberOfRowsAndColumnsBasedOnSeedPatten(seedPatternCells);
drawBoundaries();
placeSeedPatternCellsOnCanvas(seedPatternCells);
}
...
P.S.: Sorry if this looks like a silly question; my code is going to be reviewed by an OOP guru and I'm just worried :-0
EDIT:
I read some concerns about the methods in initalizeCanvas() being over-ridden - luckily these methods are private and do no call any other methods.
Anyways, after further research on net I've started liking this more... I hope you guys agree !!??
public class Canvas {
private int numberOfRows;
private int numberOfColumns;
private final List<Cell> listOfCells = new LinkedList<Cell>();
private Canvas() {
}
public static Canvas newInstance(ParsedCells seedPatternCells) {
Canvas canvas = new Canvas();
canvas.setNumberOfRowsAndColumnsBasedOnSeedPatten(seedPatternCells);
canvas.drawBoundaries();
canvas.placeSeedPatternCellsOnCanvas(seedPatternCells);
return canvas;
}
It is generally a bad idea for a constructor to contain non-trivial code. As a rule, constructors should at most assign supplied values to fields. If an object requires complex initialization, that initialization should be the responsibility of another class (typically a factory). See Miško Hevery's great write-up on this topic: Flaw: Constructor does Real Work.
You should never call non-final methods in a constructor. Effective Java does a good job explaining why, but basically your object is not in a stable state before the constructor returns. If your constructor calls methods which are overridden by a subclass, you can get strange, undefined behavior.
Also see this answer.
Although its not the most elegant way to do it, I don't see it as flawed from OO perspective. However, if you are not calling the private method initalizeCanvas from anywhere else within the class, then you can consider moving those three lines to the constructor itself.
I see two potential issues:
Are the methods you call in initializeCanvas private or final? If they are not, it's possible for a subclass to override them and unwittingly break your constructor.
Are you doing graphics operations in the drawBoundaries method? It's good practice for a constructor to do only the minimum necessary to create a valid object. Are those operations necessary for the canvas to have a valid initial state?
It depends.
It is not bad for a constructor to call a private method, provided that the private method doesn't call other methods that could be overridden. However if the method or one of the methods that it calls could be overridden, you can run into trouble. Specifically the override method will be called before the overriding classes constructor runs and will see instance fields before they have been initialized.
A second problem if that the some of the methods in your initalizeCanvas method look like they my "publish" the current object before it has been fully initialized. This is potentially problematic if the application is multi-threaded, and could result in other threads seeing stale field values.
A private init function might be useful if you have multiple constructors where some parameters are defaulted or inferred. After everything is determined, one private init function fills in the object.
In a one-constructor class, probably not.
I'm having a problem in Java. I have a method that can be extended. The problem is, that this method calls other methods of the class, and these can be extended as well.
Consider the following class:
public class Foo {
protected int xLast;
public updateMe(int x, int y) {
updateX(x);
}
protected updateX(int x) {
this.xLast = x;
}
}
This class is extended by the following class:
public class Bar extends Foo {
protected int xAverage = 0;
protected int xCount = 0;
protected int y;
public updateMe(int x, int y) {
super.updateMe(x, y);
updateX(x);
updateY(x);
}
protected updateX(int x) {
this.xAverage = (this.xAverage * this.xCount) + x;
this.xCount++;
this.xAverage /= xCount;
}
protected updateY(int y) {
this.y = y;
}
}
And also by this class:
public class Abc extends Foo {
}
When I do the following:
Foo myBar = new Bar();
myBar.updateMe(1, 2);
The Foo.updateX method is not called, but the Bar.updateX method is called twice. There are several solutions, some don't work well or are quite ugly:
In Bar.updateX call super.updateX. This will cause both updateX methods to be called twice.
Remove the updateX call in Foo.updateMe, forcing the extending classes to call super.updateX. This will cause the class Abc to have useless code that it doesn't need, or else the Abc class will not call updateX at all.
Rename the methods so that they do not override each other. This will work, but is not safe (in the future this might be forgotten and lead to problems) and is not enforced by the language.
I am aware that this is somewhat of a code-smell, but I see no better way to do this.
Basically I am looking to do something like this: in Foo.updateMe I would like to call Foo.updateX specifically, and not just the polymorph-ed updateX.
I believe that something like the new method keyword in C# can solve my problems, but Java doesn't appear to have one, or any other way to accomplish this.
Edit:
In the end I chose just to rename the offending method. I have a just one method that causes this problem, and the solution suggested here, although sound from a design point-of-view will make this particular code harder to understand and maintain.
I'd do this:
Remove updateX() call from Bar.updateMe() since updateX() is already called by super.updateMe().
Call super.updateX() from Bar.updateX() since the method with the same name is supposed to extend functionality, not replace it.
In this case Abc won't have to be changed and both updateX() methods will be called once.
Java , all instance method calls are called by means of dynamic binding. As far as I know, there is no elegant way to accomplish what you want.
If you dont care about principles and elegance, you can check class of an instance at Foo.
public updateMe(int x, int y) {
if (getClass()==Foo.class)
updateX(x);
}
Eli, it seems that you would like to cancel OOP. First it is bad. If you need this change your design. Java is pure object oriented language and therefore all calls are polymorphic. If you extended your class and overrode some if its functionality it means that you need this and therefore this functionality should be called. This is the reason that updateX() from Bar is called.
BTW to do what you want you should create static method and call it this way: Foo.updateX().
You could also make updateX() private. Then a subclass that implements updateX() is "hiding", not "overriding" the method.
Drawbacks:
Since updateX() is conceptually part of a Template pattern, it really "feels" like it should be protected.
You can't put
abstract private void updateX();
in the superclass to force users to implement it.
All implementations of updateMe() must always remember to call updateX()
Possible Drawback and possible advantage:
All of the private updateMe() methods will get called. (for me this this was desired, YMMV)
I recently faced this problem and chose this solution, though I considered renaming the methods and something very close to the (getClass()== MyFoo.class) trick. IMO all are reasonable.
In a constructor in Java, if you want to call another constructor (or a super constructor), it has to be the first line in the constructor. I assume this is because you shouldn't be allowed to modify any instance variables before the other constructor runs. But why can't you have statements before the constructor delegation, in order to compute the complex value to the other function? I can't think of any good reason, and I have hit some real cases where I have written some ugly code to get around this limitation.
So I'm just wondering:
Is there a good reason for this limitation?
Are there any plans to allow this in future Java releases? (Or has Sun definitively said this is not going to happen?)
For an example of what I'm talking about, consider some code I wrote which I gave in this StackOverflow answer. In that code, I have a BigFraction class, which has a BigInteger numerator and a BigInteger denominator. The "canonical" constructor is the BigFraction(BigInteger numerator, BigInteger denominator) form. For all the other constructors, I just convert the input parameters to BigIntegers, and call the "canonical" constructor, because I don't want to duplicate all the work.
In some cases this is easy; for example, the constructor that takes two longs is trivial:
public BigFraction(long numerator, long denominator)
{
this(BigInteger.valueOf(numerator), BigInteger.valueOf(denominator));
}
But in other cases, it is more difficult. Consider the constructor which takes a BigDecimal:
public BigFraction(BigDecimal d)
{
this(d.scale() < 0 ? d.unscaledValue().multiply(BigInteger.TEN.pow(-d.scale())) : d.unscaledValue(),
d.scale() < 0 ? BigInteger.ONE : BigInteger.TEN.pow(d.scale()));
}
I find this pretty ugly, but it helps me avoid duplicating code. The following is what I'd like to do, but it is illegal in Java:
public BigFraction(BigDecimal d)
{
BigInteger numerator = null;
BigInteger denominator = null;
if(d.scale() < 0)
{
numerator = d.unscaledValue().multiply(BigInteger.TEN.pow(-d.scale()));
denominator = BigInteger.ONE;
}
else
{
numerator = d.unscaledValue();
denominator = BigInteger.TEN.pow(d.scale());
}
this(numerator, denominator);
}
Update
There have been good answers, but thus far, no answers have been provided that I'm completely satisfied with, but I don't care enough to start a bounty, so I'm answering my own question (mainly to get rid of that annoying "have you considered marking an accepted answer" message).
Workarounds that have been suggested are:
Static factory.
I've used the class in a lot of places, so that code would break if I suddenly got rid of the public constructors and went with valueOf() functions.
It feels like a workaround to a limitation. I wouldn't get any other benefits of a factory because this cannot be subclassed and because common values are not being cached/interned.
Private static "constructor helper" methods.
This leads to lots of code bloat.
The code gets ugly because in some cases I really need to compute both numerator and denominator at the same time, and I can't return multiple values unless I return a BigInteger[] or some kind of private inner class.
The main argument against this functionality is that the compiler would have to check that you didn't use any instance variables or methods before calling the superconstructor, because the object would be in an invalid state. I agree, but I think this would be an easier check than the one which makes sure all final instance variables are always initialized in every constructor, no matter what path through the code is taken. The other argument is that you simply can't execute code beforehand, but this is clearly false because the code to compute the parameters to the superconstructor is getting executed somewhere, so it must be allowed at a bytecode level.
Now, what I'd like to see, is some good reason why the compiler couldn't let me take this code:
public MyClass(String s) {
this(Integer.parseInt(s));
}
public MyClass(int i) {
this.i = i;
}
And rewrite it like this (the bytecode would be basically identical, I'd think):
public MyClass(String s) {
int tmp = Integer.parseInt(s);
this(tmp);
}
public MyClass(int i) {
this.i = i;
}
The only real difference I see between those two examples is that the "tmp" variable's scope allows it to be accessed after calling this(tmp) in the second example. So maybe a special syntax (similar to static{} blocks for class initialization) would need to be introduced:
public MyClass(String s) {
//"init{}" is a hypothetical syntax where there is no access to instance
//variables/methods, and which must end with a call to another constructor
//(using either "this(...)" or "super(...)")
init {
int tmp = Integer.parseInt(s);
this(tmp);
}
}
public MyClass(int i) {
this.i = i;
}
I think several of the answers here are wrong because they assume encapsulation is somehow broken when calling super() after invoking some code. The fact is that the super can actually break encapsulation itself, because Java allows overriding methods in the constructor.
Consider these classes:
class A {
protected int i;
public void print() { System.out.println("Hello"); }
public A() { i = 13; print(); }
}
class B extends A {
private String msg;
public void print() { System.out.println(msg); }
public B(String msg) { super(); this.msg = msg; }
}
If you do
new B("Wubba lubba dub dub");
the message printed out is "null". That's because the constructor from A is accessing the uninitialized field from B. So frankly it seems that if someone wanted to do this:
class C extends A {
public C() {
System.out.println(i); // i not yet initialized
super();
}
}
Then that's just as much their problem as if they make class B above. In both cases the programmer has to know how the variables are accessed during construction. And given that you can call super() or this() with all kinds of expressions in the parameter list, it seems like an artificial restriction that you can't compute any expressions before calling the other constructor. Not to mention that the restriction applies to both super() and this() when presumably you know how to not break your own encapsulation when calling this().
My verdict: This feature is a bug in the compiler, perhaps originally motivated by a good reason, but in its current form it is an artifical limitation with no purpose.
I find this pretty ugly, but it helps
me avoid duplicating code. The
following is what I'd like to do, but
it is illegal in Java ...
You could also work around this limitation by using a static factory method that returns a new object:
public static BigFraction valueOf(BigDecimal d)
{
// computate numerator and denominator from d
return new BigFraction(numerator, denominator);
}
Alternatively, you could cheat by calling a private static method to do the computations for your constructor:
public BigFraction(BigDecimal d)
{
this(computeNumerator(d), computeDenominator(d));
}
private static BigInteger computeNumerator(BigDecimal d) { ... }
private static BigInteger computeDenominator(BigDecimal d) { ... }
The constructors must be called in order, from the root parent class to the most derived class. You can't execute any code beforehand in the derived constructor because before the parent constructor is called, the stack frame for the derived constructor hasn't even been allocated yet, because the derived constructor hasn't started executing. Admittedly, the syntax for Java doesn't make this fact clear.
Edit: To summarize, when a derived class constructor is "executing" before the this() call, the following points apply.
Member variables can't be touched, because they are invalid before base
classes are constructed.
Arguments are read-only, because the stack frame has not been allocated.
Local variables cannot be accessed, because the stack frame has not been allocated.
You can gain access to arguments and local variables if you allocated the constructors' stack frames in reverse order, from derived classes to base classes, but this would require all frames to be active at the same time, wasting memory for every object construction to allow for the rare case of code that wants to touch local variables before base classes are constructed.
"My guess is that, until a constructor has been called for every level of the heierarchy, the object is in an invalid state. It is unsafe for the JVM to run anything on it until it has been completely constructed."
Actually, it is possible to construct objects in Java without calling every constructor in the hierarchy, although not with the new keyword.
For example, when Java's serialization constructs an object during deserialization, it calls the constructor of the first non-serializable class in the hierarchy. So when java.util.HashMap is deserialized, first a java.util.HashMap instance is allocated and then the constructor of its first non-serializable superclass java.util.AbstractMap is called (which in turn calls java.lang.Object's constructor).
You can also use the Objenesis library to instantiate objects without calling the constructor.
Or if you are so inclined, you can generate the bytecode yourself (with ASM or similar). At the bytecode level, new Foo() compiles to two instructions:
NEW Foo
INVOKESPECIAL Foo.<init> ()V
If you want to avoid calling the constructor of Foo, you can change the second command, for example:
NEW Foo
INVOKESPECIAL java/lang/Object.<init> ()V
But even then, the constructor of Foo must contain a call to its superclass. Otherwise the JVM's class loader will throw an exception when loading the class, complaining that there is no call to super().
Allowing code to not call the super constructor first breaks encapsulation - the idea that you can write code and be able to prove that no matter what someone else does - extend it, invoke it, instansiate it - it will always be in a valid state.
IOW: it's not a JVM requirement as such, but a Comp Sci requirement. And an important one.
To solve your problem, incidentally, you make use of private static methods - they don't depend on any instance:
public BigFraction(BigDecimal d)
{
this(appropriateInitializationNumeratorFor(d),
appropriateInitializationDenominatorFor(d));
}
private static appropriateInitializationNumeratorFor(BigDecimal d)
{
if(d.scale() < 0)
{
return d.unscaledValue().multiply(BigInteger.TEN.pow(-d.scale()));
}
else
{
return d.unscaledValue();
}
}
If you don't like having separate methods (a lot of common logic you only want to execute once, for instance), have one method that returns a private little static inner class which is used to invoke a private constructor.
My guess is that, until a constructor has been called for every level of the heierarchy, the object is in an invalid state. It is unsafe for the JVM to run anything on it until it has been completely constructed.
Well, the problem is java cannot detect what 'statements' you are going to put before the super call. For example, you could refer to member variables which are not yet initialized. So I don't think java will ever support this.
Now, there are many ways to work around this problem such as by using factory or template methods.
Look it this way.
Let's say that an object is composed of 10 parts.
1,2,3,4,5,6,7,8,9,10
Ok?
From 1 to 9 are in the super class, part #10 is your addition.
Simple cannot add the 10th part until the previous 9 are completed.
That's it.
If from 1-6 are from another super class that fine, the thing is one single object is created in a specific sequence, that's the way is was designed.
Of course real reason is far more complex than this, but I think this would pretty much answers the question.
As for the alternatives, I think there are plenty already posted here.