Why is this class mutable? [duplicate]












38
















This question already has an answer here:




  • Why would one declare an immutable class final in Java?

    10 answers




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?










share|improve this question















marked as duplicate by Mehraj Malik, Slaw, Koray Tugay, jpmc26, coldspeed Jan 14 at 20:29


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.











  • 7





    What book is that?

    – Janez Kuhar
    Jan 14 at 7:34






  • 5





    make method getUrl final and objects of Test will be immutable.

    – Aditya Narayan Dixit
    Jan 14 at 7:43








  • 2





    @AdityaNarayanDixit Not really, you could still add mutable state in the subclass.

    – effeffe
    Jan 14 at 14:17
















38
















This question already has an answer here:




  • Why would one declare an immutable class final in Java?

    10 answers




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?










share|improve this question















marked as duplicate by Mehraj Malik, Slaw, Koray Tugay, jpmc26, coldspeed Jan 14 at 20:29


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.











  • 7





    What book is that?

    – Janez Kuhar
    Jan 14 at 7:34






  • 5





    make method getUrl final and objects of Test will be immutable.

    – Aditya Narayan Dixit
    Jan 14 at 7:43








  • 2





    @AdityaNarayanDixit Not really, you could still add mutable state in the subclass.

    – effeffe
    Jan 14 at 14:17














38












38








38


5







This question already has an answer here:




  • Why would one declare an immutable class final in Java?

    10 answers




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?










share|improve this question

















This question already has an answer here:




  • Why would one declare an immutable class final in Java?

    10 answers




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?





This question already has an answer here:




  • Why would one declare an immutable class final in Java?

    10 answers








java immutability






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 14 at 20:30









coldspeed

126k23126213




126k23126213










asked Jan 14 at 7:30









RamRam

49931126




49931126




marked as duplicate by Mehraj Malik, Slaw, Koray Tugay, jpmc26, coldspeed Jan 14 at 20:29


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.






marked as duplicate by Mehraj Malik, Slaw, Koray Tugay, jpmc26, coldspeed Jan 14 at 20:29


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.










  • 7





    What book is that?

    – Janez Kuhar
    Jan 14 at 7:34






  • 5





    make method getUrl final and objects of Test will be immutable.

    – Aditya Narayan Dixit
    Jan 14 at 7:43








  • 2





    @AdityaNarayanDixit Not really, you could still add mutable state in the subclass.

    – effeffe
    Jan 14 at 14:17














  • 7





    What book is that?

    – Janez Kuhar
    Jan 14 at 7:34






  • 5





    make method getUrl final and objects of Test will be immutable.

    – Aditya Narayan Dixit
    Jan 14 at 7:43








  • 2





    @AdityaNarayanDixit Not really, you could still add mutable state in the subclass.

    – effeffe
    Jan 14 at 14:17








7




7





What book is that?

– Janez Kuhar
Jan 14 at 7:34





What book is that?

– Janez Kuhar
Jan 14 at 7:34




5




5





make method getUrl final and objects of Test will be immutable.

– Aditya Narayan Dixit
Jan 14 at 7:43







make method getUrl final and objects of Test will be immutable.

– Aditya Narayan Dixit
Jan 14 at 7:43






2




2





@AdityaNarayanDixit Not really, you could still add mutable state in the subclass.

– effeffe
Jan 14 at 14:17





@AdityaNarayanDixit Not really, you could still add mutable state in the subclass.

– effeffe
Jan 14 at 14:17












2 Answers
2






active

oldest

votes


















56














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!





share|improve this answer



















  • 1





    Agree, but still, the state of the object (the value of url in test object) is not modified. Its just that the caller is now getting different/wrong values.

    – Ram
    Jan 14 at 8:04






  • 8





    @Ram The field mutable is added as a part of the state. So, the state is changed each time you call the getter.

    – bvdb
    Jan 14 at 8:10








  • 6





    "But as such the data is not modifiable though" - that depends on whose point of view you take. For the client, the field is private, so the only "data" that this class has is what you can get through getUrl. And that is modifiable, in fact even by simply calling the function. Imagine even that getUrl returns the same string, but still increases the counter... no consumer of Test can be sure (without ugly tricks, like inspecting the runtime type) that calling getUrl won't generate an overflow exception sometimes, but not others, depending on where your instance has been.

    – CompuChip
    Jan 14 at 13:21






  • 3





    @CompuChip catches the essence. I can sort-of agree that this is splitting hairs, but nevertheless, an arbitrary Test instance cannot be guaranteed to be immutable (as it could just as well be a mutable subclass), although all fields in Test are final and immutable. And the interface that Test presents to clients is definitely not immutable.

    – gustafc
    Jan 14 at 15:16








  • 2





    Well yes but immutable does not mean it returns same value for each instance method call. The value it provide can change, it does not mean its state has changed. You can have a RandomNumberGenerator that is immutable (where you can not modify the seed for example) but returns you a new random number each time you ask it for one.

    – Koray Tugay
    Jan 14 at 15:56



















0














An object that receives an object which is known to be of type Test would know the object to be immutable. An object receiving a non-null reference of type Test, however, would have no language-defined way of ensuring that the object identified thereby isn't mutable. Some people seem to regard this as a major worry. In general, however, I don't think it should be.



If a class is usefully inheritable, it will generally be easy to contrive a derived type that would be totally unsuitable for any non-contrived purpose. The only ways by which a language could even try to prevent that would be by greatly limiting the range of useful things that derived types can do. Outside of a few specialized kinds of classes (typically those related to security), however, it's generally better to ensure that derived classes can do useful things than worry about the possibility of them doing contrived and useless things.






share|improve this answer






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    56














    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!





    share|improve this answer



















    • 1





      Agree, but still, the state of the object (the value of url in test object) is not modified. Its just that the caller is now getting different/wrong values.

      – Ram
      Jan 14 at 8:04






    • 8





      @Ram The field mutable is added as a part of the state. So, the state is changed each time you call the getter.

      – bvdb
      Jan 14 at 8:10








    • 6





      "But as such the data is not modifiable though" - that depends on whose point of view you take. For the client, the field is private, so the only "data" that this class has is what you can get through getUrl. And that is modifiable, in fact even by simply calling the function. Imagine even that getUrl returns the same string, but still increases the counter... no consumer of Test can be sure (without ugly tricks, like inspecting the runtime type) that calling getUrl won't generate an overflow exception sometimes, but not others, depending on where your instance has been.

      – CompuChip
      Jan 14 at 13:21






    • 3





      @CompuChip catches the essence. I can sort-of agree that this is splitting hairs, but nevertheless, an arbitrary Test instance cannot be guaranteed to be immutable (as it could just as well be a mutable subclass), although all fields in Test are final and immutable. And the interface that Test presents to clients is definitely not immutable.

      – gustafc
      Jan 14 at 15:16








    • 2





      Well yes but immutable does not mean it returns same value for each instance method call. The value it provide can change, it does not mean its state has changed. You can have a RandomNumberGenerator that is immutable (where you can not modify the seed for example) but returns you a new random number each time you ask it for one.

      – Koray Tugay
      Jan 14 at 15:56
















    56














    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!





    share|improve this answer



















    • 1





      Agree, but still, the state of the object (the value of url in test object) is not modified. Its just that the caller is now getting different/wrong values.

      – Ram
      Jan 14 at 8:04






    • 8





      @Ram The field mutable is added as a part of the state. So, the state is changed each time you call the getter.

      – bvdb
      Jan 14 at 8:10








    • 6





      "But as such the data is not modifiable though" - that depends on whose point of view you take. For the client, the field is private, so the only "data" that this class has is what you can get through getUrl. And that is modifiable, in fact even by simply calling the function. Imagine even that getUrl returns the same string, but still increases the counter... no consumer of Test can be sure (without ugly tricks, like inspecting the runtime type) that calling getUrl won't generate an overflow exception sometimes, but not others, depending on where your instance has been.

      – CompuChip
      Jan 14 at 13:21






    • 3





      @CompuChip catches the essence. I can sort-of agree that this is splitting hairs, but nevertheless, an arbitrary Test instance cannot be guaranteed to be immutable (as it could just as well be a mutable subclass), although all fields in Test are final and immutable. And the interface that Test presents to clients is definitely not immutable.

      – gustafc
      Jan 14 at 15:16








    • 2





      Well yes but immutable does not mean it returns same value for each instance method call. The value it provide can change, it does not mean its state has changed. You can have a RandomNumberGenerator that is immutable (where you can not modify the seed for example) but returns you a new random number each time you ask it for one.

      – Koray Tugay
      Jan 14 at 15:56














    56












    56








    56







    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!





    share|improve this answer













    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!






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Jan 14 at 7:37









    gustafcgustafc

    23.5k75788




    23.5k75788








    • 1





      Agree, but still, the state of the object (the value of url in test object) is not modified. Its just that the caller is now getting different/wrong values.

      – Ram
      Jan 14 at 8:04






    • 8





      @Ram The field mutable is added as a part of the state. So, the state is changed each time you call the getter.

      – bvdb
      Jan 14 at 8:10








    • 6





      "But as such the data is not modifiable though" - that depends on whose point of view you take. For the client, the field is private, so the only "data" that this class has is what you can get through getUrl. And that is modifiable, in fact even by simply calling the function. Imagine even that getUrl returns the same string, but still increases the counter... no consumer of Test can be sure (without ugly tricks, like inspecting the runtime type) that calling getUrl won't generate an overflow exception sometimes, but not others, depending on where your instance has been.

      – CompuChip
      Jan 14 at 13:21






    • 3





      @CompuChip catches the essence. I can sort-of agree that this is splitting hairs, but nevertheless, an arbitrary Test instance cannot be guaranteed to be immutable (as it could just as well be a mutable subclass), although all fields in Test are final and immutable. And the interface that Test presents to clients is definitely not immutable.

      – gustafc
      Jan 14 at 15:16








    • 2





      Well yes but immutable does not mean it returns same value for each instance method call. The value it provide can change, it does not mean its state has changed. You can have a RandomNumberGenerator that is immutable (where you can not modify the seed for example) but returns you a new random number each time you ask it for one.

      – Koray Tugay
      Jan 14 at 15:56














    • 1





      Agree, but still, the state of the object (the value of url in test object) is not modified. Its just that the caller is now getting different/wrong values.

      – Ram
      Jan 14 at 8:04






    • 8





      @Ram The field mutable is added as a part of the state. So, the state is changed each time you call the getter.

      – bvdb
      Jan 14 at 8:10








    • 6





      "But as such the data is not modifiable though" - that depends on whose point of view you take. For the client, the field is private, so the only "data" that this class has is what you can get through getUrl. And that is modifiable, in fact even by simply calling the function. Imagine even that getUrl returns the same string, but still increases the counter... no consumer of Test can be sure (without ugly tricks, like inspecting the runtime type) that calling getUrl won't generate an overflow exception sometimes, but not others, depending on where your instance has been.

      – CompuChip
      Jan 14 at 13:21






    • 3





      @CompuChip catches the essence. I can sort-of agree that this is splitting hairs, but nevertheless, an arbitrary Test instance cannot be guaranteed to be immutable (as it could just as well be a mutable subclass), although all fields in Test are final and immutable. And the interface that Test presents to clients is definitely not immutable.

      – gustafc
      Jan 14 at 15:16








    • 2





      Well yes but immutable does not mean it returns same value for each instance method call. The value it provide can change, it does not mean its state has changed. You can have a RandomNumberGenerator that is immutable (where you can not modify the seed for example) but returns you a new random number each time you ask it for one.

      – Koray Tugay
      Jan 14 at 15:56








    1




    1





    Agree, but still, the state of the object (the value of url in test object) is not modified. Its just that the caller is now getting different/wrong values.

    – Ram
    Jan 14 at 8:04





    Agree, but still, the state of the object (the value of url in test object) is not modified. Its just that the caller is now getting different/wrong values.

    – Ram
    Jan 14 at 8:04




    8




    8





    @Ram The field mutable is added as a part of the state. So, the state is changed each time you call the getter.

    – bvdb
    Jan 14 at 8:10







    @Ram The field mutable is added as a part of the state. So, the state is changed each time you call the getter.

    – bvdb
    Jan 14 at 8:10






    6




    6





    "But as such the data is not modifiable though" - that depends on whose point of view you take. For the client, the field is private, so the only "data" that this class has is what you can get through getUrl. And that is modifiable, in fact even by simply calling the function. Imagine even that getUrl returns the same string, but still increases the counter... no consumer of Test can be sure (without ugly tricks, like inspecting the runtime type) that calling getUrl won't generate an overflow exception sometimes, but not others, depending on where your instance has been.

    – CompuChip
    Jan 14 at 13:21





    "But as such the data is not modifiable though" - that depends on whose point of view you take. For the client, the field is private, so the only "data" that this class has is what you can get through getUrl. And that is modifiable, in fact even by simply calling the function. Imagine even that getUrl returns the same string, but still increases the counter... no consumer of Test can be sure (without ugly tricks, like inspecting the runtime type) that calling getUrl won't generate an overflow exception sometimes, but not others, depending on where your instance has been.

    – CompuChip
    Jan 14 at 13:21




    3




    3





    @CompuChip catches the essence. I can sort-of agree that this is splitting hairs, but nevertheless, an arbitrary Test instance cannot be guaranteed to be immutable (as it could just as well be a mutable subclass), although all fields in Test are final and immutable. And the interface that Test presents to clients is definitely not immutable.

    – gustafc
    Jan 14 at 15:16







    @CompuChip catches the essence. I can sort-of agree that this is splitting hairs, but nevertheless, an arbitrary Test instance cannot be guaranteed to be immutable (as it could just as well be a mutable subclass), although all fields in Test are final and immutable. And the interface that Test presents to clients is definitely not immutable.

    – gustafc
    Jan 14 at 15:16






    2




    2





    Well yes but immutable does not mean it returns same value for each instance method call. The value it provide can change, it does not mean its state has changed. You can have a RandomNumberGenerator that is immutable (where you can not modify the seed for example) but returns you a new random number each time you ask it for one.

    – Koray Tugay
    Jan 14 at 15:56





    Well yes but immutable does not mean it returns same value for each instance method call. The value it provide can change, it does not mean its state has changed. You can have a RandomNumberGenerator that is immutable (where you can not modify the seed for example) but returns you a new random number each time you ask it for one.

    – Koray Tugay
    Jan 14 at 15:56













    0














    An object that receives an object which is known to be of type Test would know the object to be immutable. An object receiving a non-null reference of type Test, however, would have no language-defined way of ensuring that the object identified thereby isn't mutable. Some people seem to regard this as a major worry. In general, however, I don't think it should be.



    If a class is usefully inheritable, it will generally be easy to contrive a derived type that would be totally unsuitable for any non-contrived purpose. The only ways by which a language could even try to prevent that would be by greatly limiting the range of useful things that derived types can do. Outside of a few specialized kinds of classes (typically those related to security), however, it's generally better to ensure that derived classes can do useful things than worry about the possibility of them doing contrived and useless things.






    share|improve this answer




























      0














      An object that receives an object which is known to be of type Test would know the object to be immutable. An object receiving a non-null reference of type Test, however, would have no language-defined way of ensuring that the object identified thereby isn't mutable. Some people seem to regard this as a major worry. In general, however, I don't think it should be.



      If a class is usefully inheritable, it will generally be easy to contrive a derived type that would be totally unsuitable for any non-contrived purpose. The only ways by which a language could even try to prevent that would be by greatly limiting the range of useful things that derived types can do. Outside of a few specialized kinds of classes (typically those related to security), however, it's generally better to ensure that derived classes can do useful things than worry about the possibility of them doing contrived and useless things.






      share|improve this answer


























        0












        0








        0







        An object that receives an object which is known to be of type Test would know the object to be immutable. An object receiving a non-null reference of type Test, however, would have no language-defined way of ensuring that the object identified thereby isn't mutable. Some people seem to regard this as a major worry. In general, however, I don't think it should be.



        If a class is usefully inheritable, it will generally be easy to contrive a derived type that would be totally unsuitable for any non-contrived purpose. The only ways by which a language could even try to prevent that would be by greatly limiting the range of useful things that derived types can do. Outside of a few specialized kinds of classes (typically those related to security), however, it's generally better to ensure that derived classes can do useful things than worry about the possibility of them doing contrived and useless things.






        share|improve this answer













        An object that receives an object which is known to be of type Test would know the object to be immutable. An object receiving a non-null reference of type Test, however, would have no language-defined way of ensuring that the object identified thereby isn't mutable. Some people seem to regard this as a major worry. In general, however, I don't think it should be.



        If a class is usefully inheritable, it will generally be easy to contrive a derived type that would be totally unsuitable for any non-contrived purpose. The only ways by which a language could even try to prevent that would be by greatly limiting the range of useful things that derived types can do. Outside of a few specialized kinds of classes (typically those related to security), however, it's generally better to ensure that derived classes can do useful things than worry about the possibility of them doing contrived and useless things.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 14 at 20:14









        supercatsupercat

        56.6k2117150




        56.6k2117150















            Popular posts from this blog

            How to change which sound is reproduced for terminal bell?

            Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents

            Can I use Tabulator js library in my java Spring + Thymeleaf project?