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 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.
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 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 methodgetUrl
final and objects ofTest
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
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 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 methodgetUrl
final and objects ofTest
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
add a comment |
7
What book is that?
– Janez Kuhar
Jan 14 at 7:34
5
make methodgetUrl
final and objects ofTest
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
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
Jan 14 at 8:04
8
@Ram The fieldmutable
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 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
Jan 14 at 13:21
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
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 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
Jan 14 at 15:56
|
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
Jan 14 at 8:04
8
@Ram The fieldmutable
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 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
Jan 14 at 13:21
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
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 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
Jan 14 at 15:56
|
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
Jan 14 at 8:04
8
@Ram The fieldmutable
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 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
Jan 14 at 13:21
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
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 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
Jan 14 at 15:56
|
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 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 fieldmutable
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 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
Jan 14 at 13:21
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
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 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
Jan 14 at 15:56
|
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
Jan 14 at 8:04
8
@Ram The fieldmutable
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 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
Jan 14 at 13:21
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
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 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
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
|
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 Jan 14 at 20:14
supercatsupercat
56.6k2117150
56.6k2117150
add a comment |
add a comment |
7
What book is that?
– Janez Kuhar
Jan 14 at 7:34
5
make method
getUrl
final and objects ofTest
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