• Post Reply Bookmark Topic Watch Topic
  • New Topic

Private static inner classes: Immutable?  RSS feed

 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello:

From time to time I need to return several values from a private method, so I use to create auxiliary private static inner classes to group them. However, I doubt whether I should make the class immutable or not, given it's really small scope. Making the class immutable forces me to write an explicit constructor, because its fields are marked as final.

I started to make them immutable, but now I find that my code looks like bloated. I'm even doubting whether it brings any benefit, because they're used in a very specific place that only me controls, so it's unlikely that I alter its content accidentally. I'm referring to classes that neither inherit from other classes nor implement any interface, so they can't "leak" to external methods where immutability may be convenient.

What do you opine?

Thank you.
 
Campbell Ritchie
Marshal
Posts: 56578
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A private nested class (not “static inner”) is not necessarily immutable. What will happen if somebody else starts to maintain your class and doesn't understand they shouldn't alter the state of instances of that class? What if it implements an interface and you return a reference to outside your class?
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:A private nested class (not “static inner”) is not necessarily immutable. What will happen if somebody else starts to maintain your class and doesn't understand they shouldn't alter the state of instances of that class?


I think that someone would (should) understand the code in such a narrow scope, Right? In my opinion it's for the same reason why we don't validate the arguments of private methods: We take it for granted that someone who maintains the code can understand what's happening there.

For example:



I understand your opinion and, in fact, it's the one that made me make these classes immutable at the beginning. However, Isn't it over-protecting? Why in other parts of our code we take for granted some things, like in the example about the private method arguments, but not here?

Campbell Ritchie wrote:What if it implements an interface and you return a reference to outside your class?

But I said classes that neither inherit from other classes nor implement any interface. That was my point .
 
Campbell Ritchie
Marshal
Posts: 56578
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Avor Nadal wrote: . . . I think that someone would (should) understand the code in such a narrow scope, Right? . . .
You are like my mentor. He thinks that competent people will use code correctly.

Unfortunately I am a cynic of the worst kind and assume people will get things wrong. I think we are probably both right from our own starting points
 
Dave Tolls
Ranch Foreman
Posts: 3068
37
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can't make it immutable anyway, at least not as far as its use inside the class it is declared:

 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:You are like my mentor. He thinks that competent people will use code correctly.

Unfortunately I am a cynic of the worst kind and assume people will get things wrong. I think we are probably both right from our own starting points


He he he. I believe that I'm going to wonder about it again before doing any change. I've to admit that I've doubts now :P .

Dave Tolls wrote:You can't make it immutable anyway, at least not as far as its use inside the class it is declared


I think that I can. What I've been doing until now has been creating nested immutable classes and assigning the values to their final fields through the constructor. It forces me to write an explicit constructor, of course. That's why I'm saying that my code looks like a little bloated now. For example, if I converted my example this way, it would look like this:



The line return new Student (name, surname) could be written as return new Student (parts [0], parts [1]), I know. However, in other cases I can't put everything in one line and need to declare one local variable per each field of the immutable class, which adds even more visual complexity. Specially when there are 5 or 7 fields.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:Unfortunately I am a cynic of the worst kind and assume people will get things wrong....

@Avor: And for that reason alone I would favour immutability.

However, a couple of things you should probably ask yourself first before writing lots of "custom structures":
1. Is it simply an array (or Collection)?
2. Does what you're returning represent a class that is used elsewhere? Or possibly a sub/superclass of one?

If the answer to both of those questions is "no", then a third one is:
3. Do I really need to return multiple values?

Sometimes you do; but I've found that you can often get away with a single return value by breaking up the function into smaller pieces. And if you find you're doing this a lot, then it might be an indication that you haven't broken down the problem enough.

However, if the answer to those three questions is indeed "no, no, yes", then it seems to me that what you have is a custom "result" object. And for that reason alone I would:
1. Put in in a custom class; and a private nested one seems ideal unless you find that you need to access it anywhere else - and if that's the case, you can always remove (or change) the 'private' later on.
2. Make it immutable.

Oddly enough, a very similar question has been asked here; and you may find some of the replies helpful.

HIH

Winston
 
Dave Tolls
Ranch Foreman
Posts: 3068
37
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Avor Nadal wrote:
Dave Tolls wrote:You can't make it immutable anyway, at least not as far as its use inside the class it is declared


I think that I can. What I've been doing until now has been creating nested immutable classes and assigning the values to their final fields through the constructor. It forces me to write an explicit constructor, of course. That's why I'm saying that my code looks like a little bloated now. For example, if I converted my example this way, it would look like this:


Ha!

Good point.

Brain fart...
Back to what I was doing.
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski: After many years writing convoluted code, I came to a conclusion very similar to yours. Nowadays I break up my methods in smaller pieces every time. I even enjoy it. So it makes me happy to know that's a right way of doing things.

However, there are times when you can't get rid of nested classes. If the method that obtains the values that you want is heavy (because it has to access a big table in a database, for example), it's better to do it in a single step and return a group of values together, instead of calling the method for each of that values. The example that I wrote earlier was just by way of illustration.

I still have doubts about whether to make these type of nested classes immutable, though. I understand that making them immutable, as I already do, has the benefit that no one can change the value of any of its fields once the instance has been obtained. However, someone who were maintaining my class and felt tempted to do that, perfectly could go and edit the own nested class, removing the final modifier in one of its fields, Right? After all, if it's the maintainer of the class, it could do anything with the nested class.

That would be very different if the nested class inherited from a public class or implemented an interface, because it could "escape" from this very specific context and be altered by an external method. But I insist in that I'm talking about nested classes which mere function starts and end there, in a private method.

Dave Tolls: Don't worry, that happens to me very often ;) .
 
Campbell Ritchie
Marshal
Posts: 56578
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Avor Nadal wrote: . . . someone who were maintaining my class . . . could go and edit the own nested class, removing the final modifier in one of its fields, . . .
You can protect your code against mistakes, but not against idiots
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Avor Nadal wrote:I still have doubts about whether to make these type of nested classes immutable, though. I understand that making them immutable, as I already do, has the benefit that no one can change the value of any of its fields once the instance has been obtained...

There's actually a bit more to it than just that. Immutable classes can also share internals, and even cache values, which is one of the reasons that most of the Java wrapper classes have one. They're also usually inherently Thread-safe, which can be one less thing to worry about.

That would be very different if the nested class inherited from a public class or implemented an interface, because it could "escape" from this very specific context and be altered by an external method. But I insist in that I'm talking about nested classes which mere function starts and end there, in a private method.

I think, before I did, I'd ask myself: Why do I want to make this class mutable? Especially if it already works fine as an immutable one. I have to admit to a slight bias here, but I generally follow Josh Bloch's advice to "favour immutability", unless there's some overriding reason why I shouldn't.

Campbell Ritchie wrote:You can protect your code against mistakes, but not against idiots

I dunno. I've generally found 'final' to be a pretty good "idiot-proofer" - in all its guises - but you're quite right: nothing can protect your code from an idiot developer.

Winston
 
Dave Tolls
Ranch Foreman
Posts: 3068
37
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:... nothing can protect your code from an idiot developer.

Winston


What's everyone looking at me for??
:?
 
Campbell Ritchie
Marshal
Posts: 56578
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dave Tolls wrote: . . .
What's everyone looking at me for??
:?
Because I have finally managed to divert such attention from myself
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:There's actually a bit more to it than just that. Immutable classes can also share internals, and even cache values, which is one of the reasons that most of the Java wrapper classes have one. They're also usually inherently Thread-safe, which can be one less thing to worry about.


I know, I know ;) . I only meant so in the case of nested classes that only work as containers to return values in a very limited scope. Obviously, in other context, an immutable class has a big potential.


Winston Gutkowski wrote:I think, before I did, I'd ask myself: Why do I want to make this class mutable? Especially if it already works fine as an immutable one. I have to admit to a slight bias here, but I generally follow Josh Bloch's advice to "favour immutability", unless there's some overriding reason why I shouldn't.


My motivation is code clarity. Because when I use an immutable class, it requires declaring a new local variable for each field before calling the constructor. Having to be so redundant about the types (first with the fields, later with the constructor and finally with the local variables) makes my code harder to read in my opinion. However, I've to admit that using the special features of an IDE, such as the field/method navigator or the code folding, help not to get lost.

Anyway, I've decided to preserve these classes as immutable and use the aid of the IDE ;) . I've tried to replace them with their mutable counterparts, but I've felt myself "naked" XD . I can't describe it better. I guess that I've gotten so used to favour immutability that now I feel it as necessary.

 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Avor Nadal wrote:My motivation is code clarity. Because when I use an immutable class, it requires declaring a new local variable for each field before calling the constructor. Having to be so redundant about the types (first with the fields, later with the constructor and finally with the local variables) makes my code harder to read in my opinion.

Really? Surely those classes, however they're designed, are still going to have to set those values? Either Bean-style, or possibly "Builder"-style (ie, with chained setters). I have to admit to liking the latter approach, but I'm not sure it would convince me to make a class mutable when there's no good need. I also doubt it would make then any smaller than they are now.

Winston
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Really? Surely those classes, however they're designed, are still going to have to set those values? Either Bean-style, or possibly "Builder"-style (ie, with chained setters). I have to admit to liking the latter approach, but I'm not sure it would convince me to make a class mutable when there's no good need. I also doubt it would make then any smaller than they are now.

Winston


Finally I've decided to leave them as immutable and take advantage of the tools of the IDE to navigate through my code in a simpler way ;) .
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Avor Nadal wrote:Finally I've decided to leave them as immutable and take advantage of the tools of the IDE to navigate through my code in a simpler way ;) .

I suspect that's wise. There may be certain cases where making them mutable is an advantage, but as a general rule I'd stick to immutable ones.

Fun question though.

Winston
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!