1

I know this could be achieved via setters but in existing code, all models have public fields and I don't want a breaking change. I want the fields which are explicitly set to null to appear in serialized json but the properties which are not set should not be present.

Javascript differentiates between undefined and null. Is there a similar provision in Java?

I'm using gson for serialization/deserialization.

Bilal
  • 157
  • 1
  • 5
  • There is no way to differentiate that in Java code. If you look at the bytecode you might find some differences, maybe... – Sweeper Aug 05 '19 at 07:39
  • You could keep a separate boolean field to track if your property has ever been set. – khelwood Aug 05 '19 at 07:41
  • @khelwood how would you know it if I wrote `object.fieldName = null;`? – Andrew Tobilko Aug 05 '19 at 07:55
  • I wouldn't. That's why setters exist. – khelwood Aug 05 '19 at 08:09
  • You said you don't want breaking changes, but would something like [this](https://dzone.com/articles/null-object-pattern-in-java) help? You would just need to create a custom serializer that would serialize the null object... – Fred Aug 28 '19 at 06:58

1 Answers1

1

Without additional code that is not possible in Java.

Regarding that requirement you could either go with a approach as @khelwood mentioned, but in that case you would have to adjust the caller code (which might or might not be tricky).

I would consider the use of aspectj. That way could would not have to change any code and create a pointcut guarding all your setter of your model class. The apsect itself could keep track of which methods where called on which object. The code would have to be written with care though since threading could be an issue.

This approach is way more complex but depending on your scenario it might be worth the effort.

Another thought

You maybe just initialize every field with a constant you recognize as "undefined". You would just have to make sure, that those values CANNOT be set by the "real" application.

Rainer
  • 761
  • 5
  • 20
  • Does AspectJ trigger when you explicitly set a field rather than use a setter? i.e. foo.publicBar = baz as compared to foo.setBar(baz)? The "undefined" default-value approach seems like the simpler solution here, as long as that value is as you said not a value that would be used. – trappski Aug 05 '19 at 08:27
  • @trappski you have to come up with default values for each type... What would the default value be for a String field that could be any String? `"THERE_IS_A_LITTLE_CHANCE_THIS_WILL_BE_SET_BY_CLIENT"`? :) – Andrew Tobilko Aug 05 '19 at 08:33
  • @AndrewTobilko This goes for any Object not limited to specific values. It boils down to the domain what could be a plausible defualt if any. If not well, then this suggested solution simply isn't meant to be. – trappski Aug 05 '19 at 08:46
  • @trappski as long as you do not set it via reflection it can. https://stackoverflow.com/questions/22871250/does-a-set-field-pointcut-get-invoked-if-field-is-set-via-reflection – Rainer Aug 05 '19 at 13:34