Java's biggest mistake here, IMHO, was to have a serialization setup that was based solely on a generic interface rather than having the caller declare up front what class it expects to see. In the latter case, so long as you aren't storing naked Object/Serializable fields, type limits strongly restrict the set of naughty objects that can show up in your deserialized object graph. Rust Serde gets this right.