Java Class Constructors
Class Constructors
Constructors are a special type of method that is called when an instance of a class is created. They are used to setup the object before it is used. You can assign instance variables values and also invoke methods in the class constructor.
Constructors are written with an access modifier followed by the name of the class.
public class User {
// Constructor
public User() {
}
// ...
}
The return type of a constructor isn't provided because it is always the class type the constructor is declared in.
Assigning Instance Variables
Instance variables should usually be marked as private and can be assigned a value inside of a constructor.
public class User {
private UUID id;
private String name;
private String thumbnailName;
public User() {
id = UUID.randomUUID();
name = "default";
thumbnailName = "default";
}
// ...
}
This assigned values to each of the instance variables in the class.
Instance variable values are assigned a value before the constructor is called. In the previous example, it would be better to assign them when they are declared, simplifying the code.
public class User {
private UUID id = UUID.randomUUID();
private String name = "default";
private String thumbnailName = "default";
// ....
}
Constructor Parameters
When creating an instance of a class, it is common to pass in arguments to the constructor. Constructors can have parameters just like methods. This allows you to setup the instance and assign values to the instance variables in the class. Using the previous example, you could provide a constructor that takes all of the values and assigns them to the instance variables.
public class User {
private UUID id;
private String name;
private String thumbnailName;
public User(
final UUID id,
final String name,
final String thumbnailName) {
this.id = id;
this.name = name;
this.thumbnailName = thumbnailName;
}
// ...
}
You will notice the this keyword. The this keyword is used to reference something in the class. The this keyword is to prevent shadowing. Anytime you have shadowing, use the this keyword to prevent it. If you don't need to worry about shadowing, you don't need to use the this keyword. For example, if the constructor parameters were named differently than the instance variables in the class, you wouldn't need to use the this keyword. You generally want to name the constructor parameters the same as the instance variables if they are used to assign values to the instance variables.
final Instance Variables
Instance variables in classes can be marked as final. If they are marked as final, you either need to assign the value when they are declared or inside the constructor.
public class User {
private final UUID id;
private final String name;
private final String thumbnailName;
public User(
final UUID id,
final String name,
final String thumbnailName) {
this.id = id;
this.name = name;
this.thumbnailName = thumbnailName;
}
// ...
}
This shows an example of assigning the values to final variables in the constructor.
Constructor Overloading
Constructors can be overloaded just like methods can be overloaded.
public class User {
private UUID id;
private String name;
private String thumbnailName;
public User(
final UUID id,
final String name,
final String thumbnailName) {
this.id = id;
this.name = name;
this.thumbnailName = thumbnailName;
}
public User(final User user) {
id = user.id;
name = user.name;
thumbnailName = user.thumbnailName;
}
public User() {
}
// ...
}
This declares three constructors. The first is what was in the previous example. The second is a copy constructor. A copy constructor is a way to clone an object. A copy constructor takes the same class type and copies all of the values into the instance. You will notice that you can access the instance variables directly as if they weren't private. That is because you are inside the same User class even though it is a different instance. The third constructor is a non-args constructor.
Calling Other Constructors
When you are working with multiple constructors, you want to have a master constructor. What this means is that you have one constructor that does all of the work. The other constructors just call the master constructor, passing the arguments to it. You can do this by invoking other constructors in a constructor. Invoking another constructor is done by calling the this() method. The previous example would be better implemented as the following:
public class User {
private UUID id;
private String name;
private String thumbnailName;
public User(
final UUID id,
final String name,
final String thumbnailName) {
this.id = id;
this.name = name;
this.thumbnailName = thumbnailName;
}
public User(final User user) {
this(
user.id;
user.name;
user.thumbnailName;
)
}
public User() {
this(null, null, null)
}
// ...
}
The this() call must be the first line in the constructor, or it will result in a compiler error.
Calling Superclass Constructors
Similar to calling other constructors using this(), you can call the constructors in a superclass using super(). The super() call must be the first line in the constructor, or it will result in a compiler error.
public class User {
private UUID id;
private String name;
private String thumbnailName;
public User(
final UUID id,
final String name,
final String thumbnailName) {
this.id = id;
this.name = name;
this.thumbnailName = thumbnailName;
}
public User() {
this(null, null, null)
}
// ...
}
public class AdminUser extends User {
public AdminUser(
final UUID id,
final String name,
final String thumbnailName) {
super(id, name, thumbnailName);
}
public AdminUser() {
}
}
In the AdminUser class, the three-argument constructor calls the three-argument constructor in the User class. In the no-args constructor, there isn't a call to super(). A subclass always has to call a constructor in the superclass. If the superclass has a no-args constructor, it will call that without you having to specify it. If the superclass doesn't have a no-args constructor, you have to use a super() call and specify which constructor to use.
In a constructor, you cannot use both this() and super(). You can only use one or the other. You can have one constructor that uses this() to call a constructor that has a super() call in it.
public class User {
private UUID id;
private String name;
private String thumbnailName;
public User(
final UUID id,
final String name,
final String thumbnailName) {
this.id = id;
this.name = name;
this.thumbnailName = thumbnailName;
}
// ...
}
public class AdminUser extends User {
public AdminUser(
final UUID id,
final String name,
final String thumbnailName) {
super(id, name, thumbnailName);
}
public AdminUser() {
this(null, null, null);
}
}
Default No-args Constructors
Every Java class has a constructor. If you don't provide one, a public no-args constructor is created for you at compile time. If you provide one or more constructors, the compiler will not generate a no-args constructor for you. If you need multiple constructors, including a no-args constructor, then you will have to provide it yourself. If you only need a public no-args constructor, don't write it and just allow the compiler to create it for you.
Exceptions in Constructors
Exceptions can be thrown in constructors and can have a throws clause if you are dealing with checked exceptions. Throwing exceptions in constructors is bad and should be avoided if you can.
Conclusion
Constructors are a block of code that is invoked when you create an instance of a class. Use the this keyword when you are dealing with shadowing. When working with inheritance, you always have to specify what constructor you want to use in the superclass. If one isn't specified, it will use the no-args constructor.