Constructors and strings
Objects and text12 min readLesson 2 of 5
2.1 Constructors initialize new objects
Constructors initialize every new object. A constructor has the same name as its class and declares no return type, including void. Its job is to put the object into a valid starting state.
new Student("Asha", 16) creates the object and then calls the matching constructor with two arguments. The constructor assigns those arguments to the object's fields. When a class declares no constructor at all, the compiler supplies a default no-argument constructor.
Once you declare any constructor, that default disappears. If you still need new Student(), declare a no-argument constructor yourself and have it fill in default values or call another constructor.
public class Main {
public static void main(String[] args) {
Student student = new Student("Asha", 16);
System.out.println(student.name);
System.out.println(student.age);
}
}
class Student {
String name;
int age;
Student(String name, int age) {
this.name = name;
this.age = age;
}
}Output
Asha 16
2.1.1 this, overloads, and validation
Inside a constructor, the keyword this refers to the object being built. When a parameter has the same name as a field, this.name = name; assigns the parameter to the field. Without this, the left side would refer to the parameter.
A constructor can call another constructor of the same class with this(...). That call must be the first statement in the constructor body. Chaining keeps default values in one place; the no-argument constructor can call this(0, 0) and leave the field assignments to the fuller constructor.
Constructors can validate input before storing it. If a value is invalid, reject it with an exception or replace it with a documented default. Choose one rule and keep it consistent, because every caller relies on the object starting in a usable state.
public class Main {
public static void main(String[] args) {
Point a = new Point();
Point b = new Point(4, 7);
System.out.println(a.x + "," + a.y);
System.out.println(b.x + "," + b.y);
}
}
class Point {
int x;
int y;
Point() {
this(0, 0);
}
Point(int x, int y) {
this.x = x;
this.y = y;
}
}Output
0,0 4,7
2.1.2 Strings are immutable objects
A String is an object that holds text. Immutability means a String's characters cannot change after the object is created. Methods such as toUpperCase, trim, and substring return a new String. They do not edit the original.
Because the characters cannot change underneath other code, sharing a String reference is safe. The rule also means repeated concatenation creates new strings. Assigning the result back to a variable updates the reference, as in name = name.trim();, while the original text remains unchanged in the old object.
Useful methods include length(), charAt(index), substring(start, end), contains(text), indexOf(text), replace(old, new), and trim(). Indexes start at 0, substring(start, end) includes the start index and excludes the end index, and charAt returns a char.
public class Main {
public static void main(String[] args) {
String text = " Java Basics ";
String clean = text.trim();
System.out.println(clean.length());
System.out.println(clean.toUpperCase());
System.out.println(clean.substring(5));
System.out.println(clean.contains("Basic"));
}
}Output
11 JAVA BASICS Basics true
2.1.3 Comparing text correctly
== on two String variables asks whether they refer to the same object. It does not ask whether the text is the same. Two strings with identical characters can be different objects, so == can return false when you expected true.
Use equals for content: answer.equals("yes"). Use equalsIgnoreCase when letter case should not matter. String literals are interned, and Java may reuse the same object for identical literals, so == can appear to work on simple examples. That result depends on how the strings were created.
When one side might be null, put the literal first: "yes".equals(answer). This test returns false for a null answer without throwing NullPointerException.
public class Main {
public static void main(String[] args) {
String first = "java";
String second = "java";
String third = new String("java");
System.out.println(first == second);
System.out.println(first == third);
System.out.println(first.equals(third));
}
}Output
true false true
2.1.4 Building longer text
Joining strings with + produces a new String value. For a few pieces this is easy to read. For many pieces, especially inside a loop, a StringBuilder provides a mutable buffer.
new StringBuilder() creates an empty builder. append(value) adds text to the end, insert(index, text) adds at a position, and toString() returns the finished String. A builder is a different type, so pass builder.toString() when a method expects a String.
StringBuilder lives in java.lang, so it needs no import. Its methods change the builder and usually return the same builder so calls can be chained.
public class Main {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder();
builder.append("Java");
builder.append(" notes");
builder.append(" are ready.");
String result = builder.toString();
System.out.println(result);
}
}Output
Java notes are ready.
2.1.5 Giving objects readable text
Every class you write inherits from Object, which provides a toString method. Printing an object calls its toString method. The default output contains the class name and a hash-like value, which is rarely useful to a reader.
Override toString to return the fields that describe the object. Add @Override above the method so the compiler checks that it really overrides a superclass method. An override has the same name, no parameters, and a String return type.
Keep the returned text stable enough for logs and debugging. Do not put a password or another secret in it. If the class has many fields, a short summary is easier to read than a line containing every value.
public class Main {
public static void main(String[] args) {
Course course = new Course("Java", 9);
System.out.println(course);
}
}
class Course {
private String title;
private int lessons;
Course(String title, int lessons) {
this.title = title;
this.lessons = lessons;
}
@Override
public String toString() {
return title + ": " + lessons + " lessons";
}
}Output
Java: 9 lessons
2.1.6 Practice
- Create a
Studentclass with a constructor that takes a name and an age. - Add a no-argument constructor that calls the two-argument constructor with default values.
- Create two students, print their fields, and compare their names with
equals. - Build a sentence with
StringBuilder, then print its length and content. - Override
toStringin the student class and print a student object directly. Compare it with the output before the override.
For step 2, make sure this(...) is the first statement in the no-argument constructor.
