Why is this class mutable? [duplicate]
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:
- Only one instance variable which is private and final.
- No setters.
- The only way to initialize the instance variable is through the constructor.
- 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?
java immutability
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.
add a comment |
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:
- Only one instance variable which is private and final.
- No setters.
- The only way to initialize the instance variable is through the constructor.
- 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?
java immutability
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 methodgetUrl
final and objects ofTest
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
add a comment |
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:
- Only one instance variable which is private and final.
- No setters.
- The only way to initialize the instance variable is through the constructor.
- 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?
java immutability
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:
- Only one instance variable which is private and final.
- No setters.
- The only way to initialize the instance variable is through the constructor.
- 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
java immutability
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 methodgetUrl
final and objects ofTest
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
add a comment |
7
What book is that?
– Janez Kuhar
2 days ago
5
make methodgetUrl
final and objects ofTest
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
add a comment |
2 Answers
2
active
oldest
votes
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!
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 fieldmutable
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 isprivate
, so the only "data" that this class has is what you can get throughgetUrl
. And that is modifiable, in fact even by simply calling the function. Imagine even thatgetUrl
returns the same string, but still increases the counter... no consumer ofTest
can be sure (without ugly tricks, like inspecting the runtime type) that callinggetUrl
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 arbitraryTest
instance cannot be guaranteed to be immutable (as it could just as well be a mutable subclass), although all fields inTest
are final and immutable. And the interface thatTest
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 aRandomNumberGenerator
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
|
show 7 more comments
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.
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
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!
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 fieldmutable
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 isprivate
, so the only "data" that this class has is what you can get throughgetUrl
. And that is modifiable, in fact even by simply calling the function. Imagine even thatgetUrl
returns the same string, but still increases the counter... no consumer ofTest
can be sure (without ugly tricks, like inspecting the runtime type) that callinggetUrl
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 arbitraryTest
instance cannot be guaranteed to be immutable (as it could just as well be a mutable subclass), although all fields inTest
are final and immutable. And the interface thatTest
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 aRandomNumberGenerator
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
|
show 7 more comments
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!
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 fieldmutable
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 isprivate
, so the only "data" that this class has is what you can get throughgetUrl
. And that is modifiable, in fact even by simply calling the function. Imagine even thatgetUrl
returns the same string, but still increases the counter... no consumer ofTest
can be sure (without ugly tricks, like inspecting the runtime type) that callinggetUrl
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 arbitraryTest
instance cannot be guaranteed to be immutable (as it could just as well be a mutable subclass), although all fields inTest
are final and immutable. And the interface thatTest
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 aRandomNumberGenerator
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
|
show 7 more comments
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!
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!
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 fieldmutable
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 isprivate
, so the only "data" that this class has is what you can get throughgetUrl
. And that is modifiable, in fact even by simply calling the function. Imagine even thatgetUrl
returns the same string, but still increases the counter... no consumer ofTest
can be sure (without ugly tricks, like inspecting the runtime type) that callinggetUrl
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 arbitraryTest
instance cannot be guaranteed to be immutable (as it could just as well be a mutable subclass), although all fields inTest
are final and immutable. And the interface thatTest
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 aRandomNumberGenerator
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
|
show 7 more comments
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 fieldmutable
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 isprivate
, so the only "data" that this class has is what you can get throughgetUrl
. And that is modifiable, in fact even by simply calling the function. Imagine even thatgetUrl
returns the same string, but still increases the counter... no consumer ofTest
can be sure (without ugly tricks, like inspecting the runtime type) that callinggetUrl
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 arbitraryTest
instance cannot be guaranteed to be immutable (as it could just as well be a mutable subclass), although all fields inTest
are final and immutable. And the interface thatTest
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 aRandomNumberGenerator
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
|
show 7 more comments
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.
add a comment |
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.
add a comment |
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.
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.
answered 2 days ago
supercatsupercat
56.5k2117150
56.5k2117150
add a comment |
add a comment |
7
What book is that?
– Janez Kuhar
2 days ago
5
make method
getUrl
final and objects ofTest
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