The @Lazy transform renames the backing field to "make it more hidden" and doesn't provide a setter, hence making the field read-only (apart from reflection tricks).
Here animal becomes $animal. The intention is to disallow the fields use anymore apart from the sanctioned initialization code provided by the transform. No attempt is made to rename usages of the field that may otherwise occur within the class. Hence adding an explicit getter or setter in the normal way yields a StackOverflowError when trying to access the original property or MissingFieldException if trying to access the field directly, i.e. this.@animal. The transform should instead issue an error if explicit getters/setters are found. It would still be possible to access the $animal field (which in general may or may not be initialized) if there was really a need, just not in the standard getter or setter.