I need to have a copy constructor in my class as i need to create duplicate objects. I believe that if i will create a copy constructor, I will have to specify the non parameterized constructor too as Java will no longer provide the default constructor.
I don't want to touch the default constructor as that is what i being used in the code everywhere. Is there a workaround to have either a copy constructor or something like it without defining the basic constructor.
No, if you want to have both a parameterless constructor and a constructor with parameters, you need to declare them both. It's very easy to declare the parameterless constructor though:
public YourClassName() {
}
The super(); is implicit.
That will behave exactly the same way as the default constructor would, although it won't necessarily have the same access as the default constructor. (You can change it from being public if you want, of course.) From the JLS section 8.8.9:
If a class contains no constructor declarations, then a default constructor with no formal parameters and no throws clause is implicitly declared.
If the class being declared is the primordial class Object, then the default constructor has an empty body. Otherwise, the default constructor simply invokes the superclass constructor with no arguments.
It is a compile-time error if a default constructor is implicitly declared but the superclass does not have an accessible constructor (§6.6) that takes no arguments and has no throws clause.
In a class type, if the class is declared public, then the default constructor is implicitly given the access modifier public (§6.6); if the class is declared protected, then the default constructor is implicitly given the access modifier protected (§6.6); if the class is declared private, then the default constructor is implicitly given the access modifier private (§6.6); otherwise, the default constructor has the default access implied by no access modifier.
If you really do not want to write the default constructor, you can do:
public static MyClass create(MyClass original) {
// return the new instance
}
Related
Consider this code:
class Test {
Test() {
System.out.println("In constructor of Superclass");
}
int adds(int n1, int n2) {
return(n1+n2);
}
void print(int sum) {
System.out.println("the sums are " + sum);
}
}
class Test1 extends Test {
Test1(int n1, int n2) {
System.out.println("In constructor of Subclass");
int sum = this.adds(n1,n2);
this.print(sum);
}
public static void main(String[] args) {
Test1 a=new Test1(13,12);
Test c=new Test1(15,14);
}
}
If we have a constructor in super class, it will be invoked by every object that we construct for the child class (ex. Object a for class Test1 calls Test1(int n1, int n2) and as well as its parent Test()).
Why does this happen?
The output of this program is:
In constructor of Superclass
In constructor of Subclass
the sums are 25
In constructor of Superclass
In constructor of Subclass
the sums are 29
Because it will ensure that when a constructor is invoked, it can rely on all the fields in its superclass being initialised.
see 3.4.4 in here
Yes. A superclass must be constructed before a derived class could be constructed too, otherwise some fields that should be available in the derived class could be not initialized.
A little note:
If you have to explicitly call the super class constructor and pass it some parameters:
baseClassConstructor(){
super(someParams);
}
then the super constructor must be the first method call into derived constructor.
For example this won't compile:
baseClassConstructor(){
foo();
super(someParams); // compilation error
}
super() is added in each class constructor automatically by compiler.
As we know well that default constructor is provided by compiler automatically but it also adds super() for the first statement.If you are creating your own constructor and you don't have either this() or super() as the first statement, compiler will provide super() as the first statement of the constructor.
Java classes are instantiated in the following order:
(at classload time)
0. initializers for static members and static initializer blocks, in order
of declaration.
(at each new object)
create local variables for constructor arguments
if constructor begins with invocation of another constructor for the
class, evaluate the arguments and recurse to previous step. All steps
are completed for that constructor, including further recursion of
constructor calls, before continuing.
if the superclass hasn't been constructed by the above, construct the
the superclass (using the no-arg constructor if not specified). Like #2,
go through all of these steps for the superclass, including constructing
IT'S superclass, before continuing.
initializers for instance variables and non-static initializer blocks, in
order of declaration.
rest of the constructor.
That´s how Java works. If you create a child object, the super constructor is (implicitly) called.
In simple words if super class has parameterized constructor, you need to explicitly call super(params) in the first line of your child class constructor else implicitly all super class constructors are called untill object class is reachead.
The subclass inherits fields from it's superclass(es) and those fields have to get constructed/initialised (that's the usual purpose of a constructor: init the class members so that the instance works as required. We know that some people but a lot more functionality in those poor constructors...)
Constructor implements logic that makes the object ready to work. Object may hold state in private fields, so only its class' methods can access them. So if you wish instance of your subclass be really ready to work after calling constructor (i.e. all its functionality including inherited from base class is OK) the base class's constructor must be called.
This is why the system works this way.
Automatically the default constructor of base class is called. If you want to change this you have to explicitly call constructor of base class by writing super() in the first line of your subclass' constructor.
The base class constructor will be called before the derived class constructor. This makes sense because it guarantees that the base class is properly constructed when the constructor for the derived class is executed. This allows you to use some of the data from the base class during construction of the derived class.
When we create an object of subclass, it must take into consideration all the member functions and member variables defined in the superclass. A case might arise in which some member variable might be initialized in some of the superclass constructors. Hence when we create a subclass object, all the constructors in the corresponding inheritance tree are called in the top-bottom fashion.
Specifically when a variable is defined as protected it will always be accessible in the subclass irrespective of whether the subclass is in the same package or not. Now from the subclass if we call a superclass function to print the value of this protected variable(which may be initialized in the constructor of the superclass) we must get the correct initialized value.Hence all the superclass constructors are invoked.
Internally Java calls super() in each constructor. So each subclass constructor calls it's superclass constructor using super() and hence they are executed in top-bottom fashion.
Note : Functions can be overridden not the variables.
Since you are inheriting base class properties into derived class, there may be some situations where your derived class constructor requires some of the base class variables to initialize its variables. So first it has to initialize base class variables, and then derived class variables. That's why Java calls first base class constructor, and then derived class constructor.
And also it doesn't make any sens to initialize child class with out initializing parent class.
Constructor of Super class in called first because all the methods in the program firstly present in heap and after compilation they stores in to the stack,due to which super class constructor is called first.
There is a default super() call in your default constructors of sub classes.
//Default constructor of subClass
subClass() {
super();
}
"If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error. Object does have such a constructor, so if Object is the only superclass, there is no problem."
(source: https://docs.oracle.com/javase/tutorial/java/IandI/super.html)
I'll try to answer this from a different perspective.
Suppose Java didn't call the super constructor for you automatically. If you inherit the class, you'd have to either call the super constructor implicitly, or rewrite it yourself. This would require you to have internal knowledge of how the super class works, which is bad. It would also require to to rewrite code, which is also not good.
I agree that calling the super constructor behind the scenes is a little unintuitive. On the other hand, I'm not sure how they could have done this in a more intuitive way.
As we know that member variables(fields)of a class must be initialized before creating an object because these fields represent the state of object. If these fields are explicitely not initilized then compiler implicitely provides them default values by calling no-argument default constructor. Thats why subclass constructor invokes super class no-argument default constructor or implicitely invoked by compiler .Local variables are not provided default values by compiler.
here your extending Test to your test1 class meaning u can access all the methods and variable of test in your test1. keep in note that u can access a class methods or variable only if memory is allocated to it and for that it need some constructor either a default or parameterized ,so here wen the compiler finds that it is extending a class it will try to find the super class constructor so that u can access all its methods.
Parents Exits First!!
And like real world Child Can't exist without the Parents..
So initialising parents(SuperClass) first is important in order to use thrm in the children(Subclass) Classes..
This question already has answers here:
constructor of subclass in Java
(6 answers)
Closed 4 years ago.
The default constructor is used when no arguments are specified when a single class is instantiated but for the subclass and superclass , we need to necessarily create the default constructors ! Why?
Note: "Default constructor" != "Zero parameters constructor". The default, if supplied, is a zero-parameters constructor, but if you explicitly write a zero-parameters constructor, that's not a default.
Why is it necessary to create a default constructor in java?
It isn't — that's why it's called a default constructor. The compiler provides it if you don't write any constructors for your class. The default constructor accepts no parameters and, if your class is a subclass, calls the zero-parameters constructor on the superclass.
This works just fine (live copy):
class Base {
}
class Derived extends Base {
}
// ...
Derived d = new Derived();
You only need to define a zero-parameters constructor if:
You want it to have different accessibility than the default (by default it has the same accessibility as the class).
You define any other constructors, but also want to have a zero-parameters constructor. This is because the compiler provides the default only if no constructors are defined (since you may not want a zero-parameters constructor).
The default constructor is the no-argument constructor automatically generated if you don't define another constructor.
However, if you define at least one constructor, the default constructor is not generated. So, don't confuse the default constructor with the constructor no-argument.
When you create class A extends class B, inside the constructor of A (default or defined), if you don't explicitly call super(...), the default super() (no-arguments) is invoked implicitly.
If you have only defined constructors with arguments in the class B, this super() - calls the constructor (no-arguments) of B - is not defined --> error.
That's the reason why you think you must have a default constructor with no arguments for subclasses.
I've been reading the article about constructors and what have been written there is:
A public class can likewise prevent the creation of instances outside
its package by declaring at least one constructor, to prevent creation
of a default constructor with public access, and by declaring no
constructor that is public.
I'm confused by declaring no constructor that is public. This is because if we don't declare any constructor at all the implicitly-declared default constructor will be implicitly declared with an access modifier of the class. Which means if the class declared as public, the default constructor will be public too. That's we can use it outside the package (create instances outside the package).
You missed this bit:
by declaring at least one constructor
That's what's preventing the default constructor from being created.
The example given has a default access (package access) constructor:
PackageOnly() { }
... so it satisfies both conditions: a) it declares at least one constructor; b) it declares no public constructors.
no, the class can ba public but the constructor can be protected for only package acces or it also can be private - mostly used with factory static method
We all know that if we don't specifically define a constructor, the compiler inserts an invisible zero-parameter constructor. I thought its access modifier was public, but in dealing with an inner class issue, I found maybe I was wrong. Here is my code:
public class Outer {
protected class ProtectedInner {
// adding a public constructor will solve the error in SubOuterInAnotherPackage class
//public ProtectedInner() {}
}
}
And there is a subclass of Outer in another package:
public class SubOuterInAnotherPackage extends Outer {
public static void main(String[] args) {
SubOuterInAnotherPackage.ProtectedInner protectedInner
= new SubOuterInAnotherPackage().new ProtectedInner(); // Error!! Can't access the default constructor
}
}
You will get an error in the main() method, but if you add a public constructor to the ProtectedInner class, that error is solved. That's why I'm thinking that the modifier of the default constructor is not public! So could anyone tell me what the access modifier of the default constructor is?
I thought its access modifier is public, but when I deal with a inner class issue, I found maybe I was wrong.
Yup. Indeed, I found myself in the same situation a couple of years ago. I was surprised by an error (through Guice injection, which made it slightly harder to find).
The key is to check the spec, in this case section 8.8.9:
In a class type, if the class is declared public, then the default constructor is implicitly given the access modifier public (§6.6); if the class is declared protected, then the default constructor is implicitly given the access modifier protected (§6.6); if the class is declared private, then the default constructor is implicitly given the access modifier private (§6.6); otherwise, the default constructor has the default access implied by no access modifier.
So in this case, your constructor is implicitly protected.
In addition to what Jon pretty well stated, here is an image example, for the visual guys.
If there is no constructor in a class, compiler automatically creates a default constructor.
Here is an example that successfully depicts the above rule:
For further reference, please refer here.
I would like to point out one more thing that I recently got.
If you define a default constructor for your class then it's acess specifier will be what you assign. For example,
public class A{
A(){
// do some stuff
}
}
Here the access specifier of the default constructor is package access and not public access (that of the class).
However
public class A{
// no constructor is defined
}
Here the compiler will sympathize with you and give you a default constructor whose access specifier will be same as the class , that is public.
The Oracle Java tutorial site has this paragraph that is confusing me:
All classes have at least one
constructor. If a class does not
explicitly declare any, the Java
compiler automatically provides a
no-argument constructor, called the
default constructor. This default
constructor calls the class parent's
no-argument constructor, or the Object
constructor if the class has no other
parent. If the parent has no
constructor (Object does have one),
the compiler will reject the program.
If all objects directly or indirectly inherit from Object how is it possible to elicit the compiler rejection spoken of? Does it have to do with the constructor being private?
If all objects directly or indirectly inherit from Object how is it possible to elicit the compiler rejection spoken of?
I think the basis is of your misunderstanding is that you are thinking that constructors are inherited. In fact, constructors are NOT inherited in Java. So consider the following example:
public class A {
public A(int i) { super(); ... }
}
public class B extends A {
public B() { super(); ... }
}
The class A:
does not inherit any constructors from Object,
does not explicitly declare a no-args constructor (i.e. public A() {...}), and
does not have a default constructor (since it does declare another constructor).
Hence, it has one and only one constructor: public A(int).
The call to super() in the B class tries to use a non-existent no-args constructor in A and gives a compilation error. To fix this, you either need to change the B constructor to use the A(int) constructor, or declare an explicit no-args constructor in A.
(Incidentally, it is not necessary for a constructor to explicitly call a superclass constructor ... as I've done. But a lot of people think it is good style to include an explicit call. If you leave it out, the Java compiler inserts an implicit call to the superclasses no-args constructor ... and that results in a compilation error if the no-args constructor does not exist or is not visible to the subclass.)
Does it have to do with the constructor being private?
Not directly. However, declaring a constructor private will prevent that constructor being called from a child class.
The key thing to understand is that the no-arg constructor will only be automatically generated if the class doesn't already have a constructor.
It's thus easy to create a class that doesn't have a no-arg constructor.
The simplest way to think of this problem is as follows:
The non-args constructor is provided as the default constructor by Java for any class you create.
The moment you create a custom constructor with arguments, Java says “hey, this class has got a custom constructor, so I am not going to bother creating/supplying the default non-args constructor!”
As a result now your class does NOT has the default non-args constructor.
This means when you create a subclass, based on your class, you need explicitly call the arguments based custom constructor that you created.
If you have a sub-class of a sub-class
class A
{
A(int i) {..}
}
class B extends A
{
}
Here the default constructor inserted into B will try to invoke A's no-argument constructor (which doesn't exist) as it only has a constructor taking one argument
The immediate superclass of the object must have a protected or public constructor (or no constructor at all, in which case one will be created). So, if I create a class that extends Object, with a private constructor only, then nothing will be able to extend my class.
Yes. A private contructor is a special instance constructor. It is commonly used in classes that contain static members only. If a class has one or more private constructors and no public constructors, then other classes (except nested classes) are not allowed to create instances of this class.
The declaration of a private constructor prevents the automatic generation of a default constructor.
EDIT:
A class defined within another class
is called a nested class. Like other
members of a class, a nested class can
be declared static or not. A
nonstatic nested class is called an
inner class. An instance of an inner
class can exist only within an
instance of its enclosing class and
has access to its enclosing class's
members even if they are declared
private.
What this means is that if you inherit from a line of class(es) that make the default no-arg constructor private (or it does not exist, for example), your sub-classes must declare a constructor in line with its parent's alternative constructor.
For example, the following declaration of Bar is not allowed:
public class Foo {
private Foo() { } // or this doesn't even exist
public Foo(int i) {
}
}
public class Bar extends Foo {
}
Let me append to all aforementioned one more interesting case where the default/no-arg constructor is infeasible, in the sense that unless it is explicitly declared, the compiler cannot assume it and yet it has nothing to do with subclassing. This is the case of having a class with a final field which expects a constructor to initialize it. For example:
class Foo extends Object {
private final Object o;
public Foo(Object o){
this.o = o;
}
}
Here it's easy to see that an instantiation of a Foo-object requires the initialization of the final field o so any invocation of Foo() - directly or not - is doomed to failure... Let me underline that the no-arg constructor in the super class (Object) exists and is publicly accessible but it is the presence of the final field (o) that deactivates it in Foo.