Welcome, dear students! We have just finished studying Classes & Objects. By now, our mindset has shifted — we have moved from procedural thinking to object-oriented thinking. We can identify objects, their properties (fields) and their behaviour (methods), express them in UML, and translate that UML into Java code.
Before we dive into today's new material, let us quickly recall the two foundational pillars of OOP that we have already met.
private; the outside can only interact through well-defined public methods (getters / setters).Think of it as a medicine capsule — the contents are hidden inside; you only interact with the outer shell.
Think of driving a car: you use the steering wheel and pedals without knowing the engine internals.
Every object we create is either mutable or immutable. Let us walk through a classroom discussion step by step — with the actual Java code at each stage so you can see exactly what changes.
StringBuilder) are mutable by default.String. Once a String is created, its characters are fixed.Student class — it has id, name, and age. It has one constructor, getters, and setters. I will create an object and visualize it. Now, my question: is this object mutable or immutable? Can we change its content after it is created?📦 Object in memory — before and after setAge(21):
main. Can we still change the object?publicprivate to public? There are still no setters. Is it still immutable?public, anyone can write ali.age = 99 directly — no setter needed! The fields must stay private!private, and there must be no setters.privateThe professor then added an array of marks to the Student class and showed that even with two rules satisfied, the object can still be modified. This leads to the discovery of the third and most surprising rule.
marks, which is an int[] array. There are no setters, and the field is private. I add a getter that returns the marks. My question — is this class immutable?private, and there are no setters. It must be immutable!getMarks() and store the result in a temporary variable. Then I change the second element through that variable. Let us print the marks before and after…The student's mark changed from 85 → 0, even though there are no setter methods and all fields are private. Because getMarks() returned the reference to the real internal array. The caller used that reference to directly write into the array's memory.
private, and there are no setters. But the object was still modified! What do you think? What is missing? What should the third rule be?getName() also returns a reference to a String. Is that a problem too?getName() returns a String. Now — is String mutable or immutable?String is immutable! Once it is created, its characters cannot be changed.getName() returns the reference to the internal String, the caller cannot change its value — because String has no method to modify its characters. It is safe to return. ✅But now — what if I change the type of
name from String to StringBuilder? StringBuilder is mutable — it has methods like .replace() and .delete(). If getName() returns the reference to a StringBuilder, the caller can call those methods and change the name — even though there is no setter!StringBuilder, or any class that can be changed after creation!String, int, double) — it is safe to return directly.Student class with the marks array? We know we cannot just remove the getter — students need to read their marks. So what is the solution?An object is immutable when its content cannot be changed after it is created. Any class that meets all of the following rules — any object created from it is immutable:
privatefinal on an array?final on a reference variable means the reference cannot be reassigned. But it does NOT prevent modifying the array's contents — marks[1] = 0 still compiles and runs. So final alone is not enough — you still need defensive copies in your getter!