Can create an Instance of Abstract Class, Salesforce Bug?
Edit: This is now explicitly blocked in a critical update that prevents one from deserializing a JSON object into an abstract class. See also @ca_peterson's answer, Tweet, and GitHub comment, and the Release Notes/Critical Update.
Future Readers: If there is not a link to the Critical Update/Release Notes announcing this feature, please feel free to comment or edit a link in to this answer (see [4]:
at the bottom of this post in edit mode).
Original Answer
abstract
is a compiler-enforced limitation. The runtime does not explicitly check for abstract or read-only properties for performance reasons. JSON.deserialize is a common trick we've used for ages to mock an sObject with read-only fields, etc. Just be aware that if you do use this trick, be very careful, as you'll run into exceptions if you try to call an abstract method. Interfaces can't be deserialized because they're not "real" classes in the same sense. Technically, this is "working as designed," but you should avoid abusing this feature any more than necessary.
Salesforce bug. We're fixing this in Spring '20 via the "Restrict Reflective Access to Non-Global Controller Constructors in Packages" critical update.
As noted in the comments to @sfdxfox's answer, similar issues exist with Type.newInstance, which this critical update also resolves, as well as removing legacy versioned behavior with these tricks that was... strange.