5

I read (for example here) that if I use field dependency injection then I cannot create immutable objects, but I don't understand how field dependency injection breaks the immutability, I can do something like below can create immutable SpringTest, no?

@Component
public final class SpringTest {

    @Autowired
    private Person person;

    // here I will have no setter methods exposing "person" object but will only have getter methods for "person" object, ensuring defensive copying etc...

}

UPDATE: Please note that my question is specifically about field injection breaking the immutability, so I want to know how my above code snippet (changed since my original questions, thanks to @Andy and others for correcting it) is breaking the immutability, I think it is not, so I think this answer is wrong about immutability with field injection.

pjj
  • 2,015
  • 1
  • 17
  • 42
  • 1
    @AndyTurner: Perhaps that should be an answer. (And yes, I misread the question. I blame lack of tea.) – Makoto Mar 26 '18 at 15:01
  • Yes, that's the point of final. It is not inherent to annotations and dependency injection, it is another effort to not break immutability. – Yassine Badache Mar 26 '18 at 15:02
  • @pjj please don't change the question you already asked. Now that doesn't compile, because you have to assign it in a constructor. – Andy Turner Mar 26 '18 at 15:04
  • @AndyTurner Oh ya, I messing up, may be should blame lack of food, just on lighter note. Let me see, thank you for your inputs. How about after making it just private? – pjj Mar 26 '18 at 15:07
  • It can still be changed. I reiterate: "Merely intending not to reassign a field is not the same as not being able to do so.". Remember, you might not be the only person ever to make changes to that file, and other people may not know (or you may forget) not to change that field. – Andy Turner Mar 26 '18 at 15:36
  • I got our point with *"Merely intending ..... to do so."*, but I want to know in technical terms how the code snippet I currently I have in question is breaking the immutability. I see your point about in future other people changing the file, but it is true for any immutable class, people can screw up your immutability in future, so I see immutability is at runtime if it is somehow possible (with existing code) to break the immutability, and this is what I am trying to understand. I think that answer (link in my question) is wrong, it is possible to create immutable class with filed injection – pjj Mar 26 '18 at 15:54

2 Answers2

4

It's mutable because you can reassign the field yourself (or from any other class in the same package).

Merely intending not to reassign a field is not the same as not being able to do so.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • In fact, nothing prevents you (=OP) in this snippet to do something like `this.person = new Person()` and completely nullify both immutability and dependency injection. – Yassine Badache Mar 26 '18 at 15:03
  • Can you please elaborate, I made the field `private final ` still it is mutable? – pjj Mar 26 '18 at 15:04
  • @pjj "please don't change the question you already asked. Now that doesn't compile, because you have to assign it in a constructor." – Andy Turner Mar 26 '18 at 15:06
  • Yes, I fixed that. My question is still around immutability wrt field injection, my bad that I just put a bad example/code. – pjj Mar 26 '18 at 15:08
1

Immutable object shouldn't be possible to modify after it's constructed.

Spring injects autowired private field after the object has been constructed. It's contradicting the immutability principle, so immutability is therefore broken.

But, in case of Autowiring via constructor injection, we are not breaking immutability as far as the field is declared private final, since this sets the value to the field only once and during object construction.

Additionally, if the Person object is mutable and you have a getter for it, then it's clearly breaking the immutability of SpringTest as well.

elyor
  • 998
  • 9
  • 20
  • I fixed that by `private Person person;`. My question is still around immutability wrt field injection, my bad that I just put a bad example/code. – pjj Mar 26 '18 at 15:08
  • @pjj Updated the answer – elyor Mar 26 '18 at 15:22