Can a class have both an open and a private constructor?
Yes it is possible.
To create a private field whose type is a private inner class, a private constructor is needed. Is it encouraged or discouraged?
It depends on situation. Do you want another class to initialize the state of your object or not. Here I think you created the CopyTree class to return a copy of the tree, which is a private class. This way, the TreeNode class will be encapsulated, therefore, it leaves you the opportunity to use the constructor capture personal identification.
What is the best solution for the scenario listed below?
In my opinion, the idiom of a personal designer is the best solution.
For more information:
You could look for a personal capture capture of the constructor .
An example is given in solution 53 of Java Puzzlers :
Puzzle 53: Do Your Thing
Now it's your turn to write the code. Suppose you have a library class called Thing, whose only constructor takes an int parameter:
public class Thing { public Thing(int i) { ... } ... }
The Thing instance does not allow you to get the value of its constructor parameter. Since Thing is a class of the library, you do not have access to its internal components, and you cannot modify it. Suppose you want to write a subclass of MyThing with a constructor that evaluates this parameter in the constructor of the superclass by calling the SomeOtherClass.func () method. The value returned by this method changes unpredictably from call to call. Finally, suppose you want to store the value that was passed to the constructor of the superclass in the field of the final instance of the subclass for future use. This is the code you naturally write:
public class MyThing extends Thing { private final int arg; public MyThing() { super(arg = SomeOtherClass.func()); ... } ... }
Unfortunately, this is not legal. If you try to compile it, you will get an error message that looks something like this:
MyThing.java: can't reference arg before supertype constructor has been called super(arg = SomeOtherClass.func()); ^
How can you rewrite MyThing to achieve the desired effect? The MyThing () constructor must be thread safe: multiple threads can reference it at the same time.
Solution 53: do your thing
You can try to hide the result of calling SomeOtherClass.func () in a static field before calling the Thing constructor. This solution works, but is inconvenient. To ensure thread safety, you must synchronize access to the stored value, which requires unimaginable distortions. Some of these distortions can be avoided by using a static field with a thread (java.util.ThreadLocal), but a much better solution exists. The preferred solution is inherently threadlike as well as elegant. This is due to the use of a second, private constructor in MyThing:
public class MyThing extends Thing { private final int arg; public MyThing() { this(SomeOtherClass.func()); } private MyThing(int i) { super(i); arg = i; } }
This solution uses an alternative constructor call. This function allows one constructor in a class to connect to another constructor in the same class. In this case, MyThing () is associated with the private constructor MyThing (int), which initializes the required instance. Inside the private constructor, the value of the SomeOtherClass.func () expression was fixed in the i parameter and can be stored in the last field parameter after the superclass constructor returns.