Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this class mutable? [duplicate]

public class Test {     private final String url;     public Test(String url) {         this.url = url;     }     public String getUrl() {         return url;     } } 

The Test class has:

  1. Only one instance variable which is private and final.
  2. No setters.
  3. The only way to initialize the instance variable is through the constructor.
  4. And once the URL is set, it can't be modified even in getUrl even if that method is overridden by any subclass of Test.

But a book that I am reading says the above Test class is mutable because:

  • Neither class is final so that it can be extended, and a subclass can override instance methods. But the Test class does not really have any instance methods other than the constructor.

  • Nor is the constructor private.

Can you please help me in understanding why the Test class is mutable?

like image 471
Ram Avatar asked Jan 14 '19 07:01

Ram


People also ask

Can immutable class be cloned?

Immutable objects are objects that don't change. You make them, then you can't change them. Instead, if you want to change an immutable object, you must clone it and change the clone while you are creating it. A Java immutable object must have all its fields be internal, private final fields.

How do you know if a class is mutable?

So, to check if class is immutable you first look at class level annotations and javadoc and only then at implementation itself. Regarding final fields: this only give the guaranty that the reference will not be changed. However, the value of a mutable field (e.g. java.

What makes a class immutable?

Immutable class means once the object of the class is created its fields cannot be modified or changed. In Java, all the wrapper classes like Boolean, Short, Integer, Long, Float, Double, Byte, Char, and String classes are immutable classes.


1 Answers

An arbitrary instance of Test isn't guaranteed to be immutable, although direct instances of Test are. But consider this subclass:

public class MutableTest extends Test {         private int mutable;         public MutableTest(String url) {                 super(url);         }          @Override         public String getUrl() {                 return super.getUrl() + mutable++;         } } 

Then you can write something like this:

Test instance = new MutableTest("http://example.com/"); String firstGet = instance.getUrl(); String secondGet = instance.getUrl(); assertEquals(firstGet, secondGet); // Boom! 
like image 77
gustafc Avatar answered Oct 08 '22 12:10

gustafc