Constructors
A constructor runs when an object is created with new, and sets it up ready to use:
class Account {
String owner;
double balance;
Account(String owner, double balance) {
this.owner = owner;
this.balance = balance;
}
void show() {
System.out.println(owner + ": " + balance);
}
}
public class Main {
public static void main(String[] args) {
Account a = new Account("Asha", 500);
Account b = new Account("Leo", 120.5);
a.show();
b.show();
}
}- A constructor has the same name as the class and no return type, not even
void. this.owneris the object's field; plainowneris the parameter.thismeans "the object being set up".
The default constructor
When a class declares no constructor at all, Java supplies an empty one with no parameters. That's why new Dog() worked in the last lesson. Declare any constructor yourself, and the free one disappears:
Account a = new Account(); // error: Account has no constructor without parametersSeveral constructors
class Pizza {
String size;
String topping;
boolean extraCheese;
Pizza(String size, String topping, boolean extraCheese) {
this.size = size;
this.topping = topping;
this.extraCheese = extraCheese;
}
Pizza(String size, String topping) {
this(size, topping, false); // call the full constructor
}
Pizza() {
this("medium", "margherita");
}
@Override
public String toString() {
return size + " " + topping + (extraCheese ? " with extra cheese" : "");
}
}
public class Main {
public static void main(String[] args) {
System.out.println(new Pizza());
System.out.println(new Pizza("large", "paneer tikka"));
System.out.println(new Pizza("small", "mushroom", true));
}
}Constructors can be overloaded like methods. this(...) calls another constructor of the same class and must be the first statement, which keeps the real set-up code in one place.
Refusing bad values
class Temperature {
double celsius;
Temperature(double celsius) {
if (celsius < -273.15) {
throw new IllegalArgumentException("Below absolute zero: " + celsius);
}
this.celsius = celsius;
}
}
public class Main {
public static void main(String[] args) {
Temperature ok = new Temperature(21.5);
System.out.println("Created: " + ok.celsius);
Temperature bad = new Temperature(-300);
System.out.println("This line never runs");
}
}The constructor is the gatekeeper: if it refuses invalid values, no invalid object can ever exist. The program above stops with an IllegalArgumentException, as intended.
final fields
class Student {
final String id;
String name;
Student(String id, String name) {
this.id = id;
this.name = name;
}
}
public class Main {
public static void main(String[] args) {
Student s = new Student("S-101", "Mei");
s.name = "Mei Tanaka"; // fine: name can change
// s.id = "S-999"; // error: id is final
System.out.println(s.id + " " + s.name);
}
}A final field must be given a value exactly once, either where it's declared or in every constructor, and can never change after that. Use it for things that shouldn't change, like an id.