It sets primitives to 0, "", false etc. Which is almost always but not always fine. And if they're complex objects you still get NPEs
To get true nullable fields you need to use pointers. That's a whole topic in itself but they're awkward.
It's much worse than true nullable objects that your compiler can check for NPEs. It throws fewer NPEs but at the expense of data integrity where you don't know if your 0 is actually a 0 from the user or a null.