Why is this class mutable? [duplicate]












33
















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 2 days ago


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
    2 days ago






  • 5





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

    – Aditya Narayan Dixit
    2 days ago








  • 2





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

    – effeffe
    2 days ago
















33
















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 2 days ago


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
    2 days ago






  • 5





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

    – Aditya Narayan Dixit
    2 days ago








  • 2





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

    – effeffe
    2 days ago














33












33








33


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 2 days ago









coldspeed

124k22125208




124k22125208










asked 2 days ago









RamRam

47431026




47431026




marked as duplicate by Mehraj Malik, Slaw, Koray Tugay, jpmc26, coldspeed 2 days ago


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 2 days ago


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
    2 days ago






  • 5





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

    – Aditya Narayan Dixit
    2 days ago








  • 2





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

    – effeffe
    2 days ago














  • 7





    What book is that?

    – Janez Kuhar
    2 days ago






  • 5





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

    – Aditya Narayan Dixit
    2 days ago








  • 2





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

    – effeffe
    2 days ago








7




7





What book is that?

– Janez Kuhar
2 days ago





What book is that?

– Janez Kuhar
2 days ago




5




5





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

– Aditya Narayan Dixit
2 days ago







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

– Aditya Narayan Dixit
2 days ago






2




2





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

– effeffe
2 days ago





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

– effeffe
2 days ago












2 Answers
2






active

oldest

votes


















53














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
    2 days ago






  • 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
    2 days ago








  • 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
    2 days ago






  • 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
    2 days ago








  • 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
    2 days ago



















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









    53














    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
      2 days ago






    • 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
      2 days ago








    • 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
      2 days ago






    • 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
      2 days ago








    • 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
      2 days ago
















    53














    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
      2 days ago






    • 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
      2 days ago








    • 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
      2 days ago






    • 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
      2 days ago








    • 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
      2 days ago














    53












    53








    53







    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 2 days ago









    gustafcgustafc

    23.4k75788




    23.4k75788








    • 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
      2 days ago






    • 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
      2 days ago








    • 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
      2 days ago






    • 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
      2 days ago








    • 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
      2 days ago














    • 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
      2 days ago






    • 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
      2 days ago








    • 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
      2 days ago






    • 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
      2 days ago








    • 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
      2 days ago








    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
    2 days ago





    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
    2 days ago




    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
    2 days ago







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

    – bvdb
    2 days ago






    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
    2 days ago





    "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
    2 days ago




    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
    2 days ago







    @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
    2 days ago






    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
    2 days ago





    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
    2 days ago













    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 2 days ago









        supercatsupercat

        56.5k2117150




        56.5k2117150















            Popular posts from this blog

            An IMO inspired problem

            Management

            Has there ever been an instance of an active nuclear power plant within or near a war zone?