4 ms·
Why does super need to go in a specific position? Isn’t “super calls the parent classes constructor” simpler than “ super calls the parent classes constructor a
by rcme 4y ago
Why does super need to go in a specific position? Isn’t “super calls the parent classes constructor” simpler than “ super calls the parent classes constructor and it must be the first statement in the child constructor.”
- revetkn 4y agoThat's how I view it as well, from an end user perspective this is removing an arbitrary rule that you're required to "just memorize" (or be surprised when your IDE complains).
- avereveard 4y agoit's simpler for the subclass. the parent class however now has to deal with an arbitrary set of operation that the sub class can perform between the initializer block and the constructor method, so it's contract is overall much harder to define, because you can no longer be sure of your internal state in the constructor.
- rcme 4y agoThis seems like a solvable problem with static analysis: don’t allow reads from instance variables / methods of the parent class until super is called.
- tsimionescu 4y agoThe problem begins when you want to do more complex things. For example, you can't call super() inside a try{} block as far as I understand, but that doesn't immediately follow from "super calls the parent class' constructor" - and it did follow from "either super() or this() must be the first statement in your constructor".
- grog454 4y agoWhat does "try {" compile to in machine instructions or any intermediate language? I always thought of it as an annotation on a scope but now I'm curious. Edit- from reading https://stackoverflow.com/questions/25007427/how-are-exceptions-caught-and-dealt-with-at-the-low-assembly-level https://stackoverflow.com/questions/25007427/how-are-excepti... it appears my suspicion was correct. try{ is effectively an annotation that has no impact on the sequence of instructions you are authoring. So it's surprising to me that it breaks the this/super first rule. OTOH it seems to me there should always be a rule to not allow execution paths that never call super nor this, and since try could break that one I'd always be leery of using it in constructors.
- tsimionescu 4y agoThe JEP itself explains the reason why this limitation exists: > try { } Blocks > The restriction that super() and this() may not appear inside a try { } block comes from the JVM itself, and is due to how StackMaps are represented. The logic is that when a superclass constructor throws an exception, the new instance on the stack is neither fully uninitialized nor fully initialized, so it should be considered unusable, and therefore such a constructor must never return. However, the JVM doesn't allow the bytecode to discard the unusable instance and throw another exception; instead, it doesn't allow it to exist on the stack at all. The net effect is that constructors can't catch exceptions thrown by superclass initialization, even if rethrown. [emphasis mine]