Constructors in Java
Constructors in Java
In Java, constructor is a block of codes similar to method. It is called when an instance of object is created and
memory is allocated for the object. It is a special type of method which is used to initialize the object.
Note: It is called constructor because it constructs the values at the time of object creation. It is not necessary to
write a constructor for a class. It is because java compiler creates a default constructor if your class doesn't have
any.
void display(){
System.out.println(id+" "+name);
}
Student6(Student6 s){
id = s.id;
name =s.name;
}
void display(){System.out.println(id+" "+name);}
When you call new Employee(60000), then the Employee(double) constructor calls the Employee(String,
double) constructor. Using the this keyword in this manner is useful—you only need to write common
construction code once.
Initialization Blocks:
You have already seen two ways to initialize a data field:
● By setting a value in a constructor
● By assigning a value in the declaration
There is actually a third mechanism in Java; it's called an arbitrary blocks of code. These blocks are executed
whenever an object of that class is constructed. For example,
class Employee
{
public Employee(String n, double s)
{
name = n;
salary = s;
}
public Employee()
{
name = "";
salary = 0;
}
. . .
private static int nextId;
private int id;
private String name;
private double salary;
. . .
// object initialization block
{
id = nextId;
nextId++;
}
}
In this example, the id field is initialized in the object initialization block, no matter which constructor is used to
construct an object. The initialization block runs first, and then the body of the constructor is executed.
This mechanism is never necessary and is not common. It usually is more straightforward to place the
initialization code inside a constructor.
Static initialization occurs when the class is first loaded. Like instance fields, static fields are 0, false, or null
unless you explicitly set them to another value. All static field initializers and static initialization blocks are
executed in the order in which they occur in the class declaration.
NOTE:
Here is a Java trivia fact to amaze your fellow Java coders: You can write a "Hello, World" program in Java
without ever writing a main
public class Hello
{
static
{
System.out.println("Hello, World");
}
}
When you invoke the class with java Hello, the class is loaded, the static initialization block prints "Hello,
World," and only then do you get an ugly error message that main is not defined. You can avoid that blemish by
calling System.exit(0) at the end of the static initialization block.
Overloading Methods:
In Java it is possible to define two or more methods within the same class that share the same name, as long as
their parameter declarations are different. When this is the case, the methods are said to be overloaded, and the
process is referred to as method overloading. Method overloading is one of the ways that Java implements
polymorphism. If you have never used a language that allows the overloading of methods, then the concept may
seem strange at first. But as you will see, method overloading is one of Java’s most exciting and useful features.
When an overloaded method is invoked, Java uses the type and/or number of arguments as its guide to
determine which version of the overloaded method to actually call. Thus, overloaded methods must differ in the
type and/or number of their parameters. While overloaded methods may have different return types, the return
type alone is insufficient to distinguish two versions of a method. When Java encounters a call to an overloaded
method, it simply executes the version of the method whose parameters match the arguments used in the call.
Overloading Constructors:
In addition to overloading normal methods, you can also overload constructor methods. In fact, for most real-
world classes that you create, overloaded constructors will be the norm, not the exception. To understand why,
let’s return to the Box class developed in the preceding chapter. Following is the latest version of Box:
THE JAVA LANGUAGE
class Box {
double width;
double height;
double depth;
// This is the constructor for Box.
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
// compute and return volume
double volume() {
return width * height * depth;
}
}
As you can see, the Box( ) constructor requires three parameters. This means that all declarations of Box objects
must pass three arguments to the Box( ) constructor. For example, the following statement is currently invalid:
Box ob = new Box();
Since Box( ) requires three arguments, it’s an error to call it without them. This raises some important questions.
What if you simply wanted a box and did not care (or know) what its initial dimensions were? Or, what if you
want to be able to initialize a cube by specifying only one value that would be used for all three dimensions? As
the Box class is currently written, these other options are not available to you. Fortunately, the solution to these
problems is quite easy: simply overload the Box constructor so that it handles the situations just described. Here
is a program that contains an improved version of Box that does just that:
// Here, Box defines three constructors to initialize the dimensions of a box various ways.
class Box {
double width;
double height;
double depth;
// constructor used when all dimensions specified
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
// constructor used when no dimensions specified
Box() {
width = -1; // use -1 to indicate
height = -1; // an uninitialized
depth = -1; // box
}
// constructor used when cube is created
Box(double len) {
width = height = depth = len;
}
// compute and return volume
double volume() {
return width * height * depth;
}
}
class OverloadCons {
public static void main(String args[]) {
// create boxes using the various constructors
Box mybox1 = new Box(10, 20, 15);
Box mybox2 = new Box();
Box mycube = new Box(7);
double vol;
// get volume of first box
vol = mybox1.volume();
System.out.println("Volume of mybox1 is " + vol);
// get volume of second box
vol = mybox2.volume();
System.out.println("Volume of mybox2 is " + vol);
THE JAVA LANGUAGE
// get volume of cube
vol = mycube.volume();
System.out.println("Volume of mycube is " + vol);
}
}
The output produced by this program is shown here:
Volume of mybox1 is 3000.0
Volume of mybox2 is -1.0
Volume of mycube is 343.0
As you can see, the proper overloaded constructor is called based upon the parameters specified when new is
executed.
As you can see, the operations that occur inside meth( ) have no effect on the values of a and b used in the call;
their values here did not change to 30 and 10.
When you pass an object to a method, the situation changes dramatically, because objects are passed by
reference. Keep in mind that when you create a variable of a class type, you are only creating a reference to an
object. Thus, when you pass this reference to a method, the parameter that receives it will refer to the same
object as that referred to by the argument. This effectively means that objects are passed to methods by use of
call-by-reference. Changes to the object inside the method do affect the object used as an argument. For
example, consider the following program:
As you can see, in this case, the actions inside meth( ) have affected the object used as an argument. As a point
of interest, when an object reference is passed to a method, the reference itself is passed by use of call-by-value.
However, since the value being passed refers to an object, the copy of that value will still refer to the same
object that its corresponding argument does.
When a simple type is passed to a method, it is done by use of call-by-value. Objects are passed by use of call-
by-reference.
Returning Objects:
A method can return any type of data, including class types that you create. For example, in the following
program, the incrByTen( ) method returns an object in which the value of a is ten greater than it is in the
invoking object.
// Returning an object.
class Test {
int a;
Test(int i) {
a = i;
}
Test incrByTen() {
Test temp = new Test(a+10);
return temp;
}
}
class RetOb {
public static void main(String args[]) {
Test ob1 = new Test(2);
Test ob2;
ob2 = ob1.incrByTen();
System.out.println("ob1.a: " + ob1.a);
System.out.println("ob2.a: " + ob2.a);
ob2 = ob2.incrByTen();
System.out.println("ob2.a after second increase: " + ob2.a);
}
}
The output generated by this program is shown here:
ob1.a: 2
ob2.a: 12
ob2.a after second increase: 22
THE JAVA LANGUAGE
As you can see, each time incrByTen( ) is invoked, a new object is created, and a reference to it is returned to
the calling routine.
The preceding program makes another important point: Since all objects are dynamically allocated using new,
you don’t need to worry about an object going out-of-scope because the method in which it was created
terminates. The object will continue to exist as long as there is a reference to it somewhere in your program.
When there are no references to it, the object will be reclaimed the next time garbage collection takes place.