标签云

微信群

扫码加入我们

WeChat QR Code

Is it possible to call a constructor from another (within the same class, not from a subclass)? If yes how? And what could be the best way to call another constructor (if there are several ways to do it)?


I believe the premise of your question is wrong. Instead of calling a constructor within a constructor, use the Factory pattern. A static factory method first creates all lower-level objects. Then it constructs the higher-level objects which gets returns from the factory call. This technique removes complexity from the model which aids maintenance, clarity, and testing.

2019年05月24日57分24秒

I generally switched to private constructors and factory methods, since constructors, because of their limitations, are violating the open-closed principle. I think this comment should be the correct answer, everything else will confuse the hell out of your team mates.

2019年05月24日57分24秒

So I supposed it's not possible to call a super constructor and another constructor of the same class as both need to be the first line?

2019年05月24日57分24秒

gsingh2011: Indeed. You can only chain to one other constructor.

2019年05月24日57分24秒

This has to appear on the first line, but you can do calculations in the constructor before it is called: You can use static methods in the arguments of this() on the first line and encapsulate any calculation which has to be performed before the call to the other constructor in that static method. (I have added this as a separate answer).

2019年05月24日57分24秒

gsingh2011 I know it's late but as a way around, you can call overloaded constructor using this(...) and then in that overloaded constructor, you can make a call to base class' constructor using super(...)

2019年05月24日57分24秒

JustinTime: Again, it depends on what you mean by "creating" - the object is "created" in that its memory is allocated and the type is set before any constructor bodies are executed. Constructors are initialization rather than creation. In particular, the type of the object is its "final" type right from the start - so if you call any virtual methods from constructors, you'll get the most-specific override called. I believe this differs from C++.

2019年05月24日57分24秒

If many constructor parameters are used, consider a builder. See Item 2 of "Effective Java" by Joshua Bloch.

2019年05月24日57分24秒

The problem with the implementation of the last approach using the factory method, newCons, is that you are trying to change state of an object, using setArg1(...), that should most likely have its fields set as final. As we are trying to keep as much as possible of an object immutable, if not completely, a builder pattern will address this issue more correctly.

2019年05月24日57分24秒

Wouldn't you rather do :: public Cons() { this(madeUpArg1Value,madeUpArg2Value);}

2019年05月24日57分24秒

Initialization should proceed from least to greatest - I would never have a default constructor call up the chain to a multi-parameter constructor.What needs to happen is that all constructors call either the default or a constructor with less parameters.

2019年05月24日57分24秒

RodneyP.Barbati It's pretty common in Java for lower-arity constructors to call greater-arity constructors and then do nothing else.if a class K has, e.g., two final fields a, b, then the "general constructor" would be K(A a, B b) { this.a = a; this.b = b; }.Then, if b has a reasonable default, there can be a one-arg constructor K(A a) { this(a, DEFAULT_B); }, and if there's a default a as well, we have a default constructor: K() { this(DEFAULT_A); }.That's a pretty common convention in Java.

2019年05月24日57分24秒

It's true that you can call static methods in this way in order to perform complex calculations for argument values, which is fine. However, if one feels that code is needed before constructor delegation (this(...)) then it would be reasonable to assume that an horrible mistake has been made somewhere and that the design perhaps needs a bit of a rethink.

2019年05月24日57分24秒

I would agree that a very complex transformation likely indicates a design issue. But 1) there are some simple transformations which for which this may be useful - not all constructors are just linear projection on others and 2) there may be other situation where this information could become hand, like supporting legacy code. (While I agree on your conclusion, I do not see why it would justify a down vote).

2019年05月24日57分24秒

This is completely in reverse of what I would suggest - the no parameter constructor should initialize all values to defaults.The 2 parameter constructor should call the no param constructor, then initialize the 2 values it receives.The 3 parameter constructor should call the 2 parameter constructor, then initialize the 3rd value to the value it receives.Doing it as shown means you have to do a lot more work to add another parameter.

2019年05月24日57分24秒

RodneyP.Barbati: I see a few issues in doing it the way you describe it: a) Doing it that way it is not possible to illustrate the use of static method in a constructor (and that is the intention of the example) ;-) and b) if you do it your way, the fields cannot be final (final fields can be initialized only once).

2019年05月24日57分24秒

RodneyP.Barbati: Two other aspects: c) I believe that you should always do the object initialisation at a single point, which has to be the most general constructor. If object initialisation requires a complex task (object init not being lazy) or checking or acquiring some resources (like a file), then you like to do that only once. And d) Adding another argument (say argument4) for which the initialisation depends on the value of argument1 to argument3 you would have to change all constructors in your case, whereas here you only have to add one and let the 3-arg call the 4-arg constructor.

2019年05月24日57分24秒

why don't you call second constructor which is Rectangle(int width, int height) in Rectangle() instead of Rectangle(int x, int y, int width, int height) ?

2019年05月24日57分24秒

A default constructor should not have knowledge of higher level constructors - it is the default.Following this pattern will result in you having to change one or more existing constructors when you add a new one.For example, add a lineWidth value and see what I mean.But have the default initialize all values, and reverse the constructor chain, you will see each constructor building on the prior, and initializing only the values which it specifically supports - You can add a new one without changing the existing ones.There are many common patterns in java that aren't good patterns.

2019年05月24日57分24秒

RodneyP.Barbati I can't agree in this case. That pattern doesn't allow for final fields.

2019年05月24日57分24秒

You have the following in the main method://this(); error because "must be first statement in constructorThis statement does not make much sense. If you are trying to say that this() cannot be called from inside main method, then yes it cannot be because main is static and will not have reference to this()

2019年05月24日57分24秒

S R Chaitanya- he is saying that the line of code that contains this(); must be the first line in the overriding constructor. You are also correct that the this keyword is meaningless in a static method.

2019年05月24日57分24秒

I don't like this approach because calling either of the constructors leaves one of the values uninitialized - in other words, you get an invalid object.Either of the one parameter constructors should call the two parameter constructor by passing null for one of the values.This way, you are guaranteed that all of the values are initialized in one place correctly.

2019年05月24日57分24秒

RodneyP.Barbati if i initialize the variables does that improve upon this issue you are addressing?

2019年05月24日57分24秒