Can a class have both an open and a private constructor?

I came across a scenario where I need a public and private constructor. To create a private field whose type is a private inner class, a private constructor is needed. Is it sheltered or discouraged? Otherwise, what is the best solution for the scenario listed below?

Please read the comment that supports my question in more detail. Thanks,

public class CopyTree { private TreeNode root; public Copytree() { } // private CopyTree(TreeNode root) { this.root = root; } private static class TreeNode { TreeNode left; TreeNode right; Integer element; TreeNode(TreeNode left, TreeNode right, Integer element) { this.left = left; this.right = right; this.element = element; } } public CopyTree copyTree() { CopyTree ct = new CopyTree(); ct.root = copyTree(root); // <---- QUESTION: Any cleaner solution ?? // cleaner solution appears to be a private constructor // eg: CopyTree ct = new CopyTree(copyTree(root)); But can public and private constructor coexist together ? return ct; } private TreeNode copyTree(TreeNode binaryTree) { TreeNode copy = null; if (binaryTree != null) { copy = new TreeNode(null, null, binaryTree.element); copy.left = copyTree(binaryTree.left); copy.right = copyTree(binaryTree.right); } return copy; } 
+6
source share
4 answers

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.

0
source

A class can be excluded from explication created by its callers using Private Constructors.

If private constructors are useful,

  • classes containing only static utility methods
  • classes containing only constants
  • safe type enumerations
  • loners

If they turned out to be a flaw (not limited to below), the list may grow)

  • Classes without public or protected constructors cannot be subclasses.
  • They cannot be easily distinguished with other static methods.
0
source

You can use both private and public constructor only as follows. But you cannot use both parameters without an argument constructor or the same type of argument.

 public class MyClass { private MyClass(){ } public MyClass(int i){ } } 
0
source

Judging by your commented code, you have already tried it, and it worked. Therefore, I can only confirm your conclusion: yes, a private constructor can coexist with a public one, and yes, this seems like a better solution, since more initialization is performed before receiving a link to a new object.

0
source

Source: https://habr.com/ru/post/948915/


All Articles