The first case (compiler defined default constructor) occurs if and only if there are no explicit constructors written. It's public if the class itself is public, and requires a no-argument superclass constructor (compiler default or explicit) that is public
or protected
. JLS
The second option, with a user defined constructor, allows you to actually put initialization code into it. Even if there are no parameters your constructor may still want to do something (for example store the timestamp of when the object was constructed to a field).
Additionally, if you are writing a subclass to this class, and you do not explicitly call a superclass constructor, the no-arg super()
constructor will be called. If it doesn't exist, this will throw an error, so you can declare a protected MyClass2(){}
to allow the subclass to make that call.