> Java doesn't even have a security model any more, so what are you protecting?
That security model was obsolete and didn't fulfill its original purpose anymore. Most applications have never enabled it.
> Programmers from their own mistakes? That's fine, but this is about cases where they set the "I really mean it and this isn't a mistake" flag.
Not at all, the vast majority of code using this feature is part of libraries. Application developers are often not aware that this even happens. Anyway, it will also in the future be possible for developers to shoot themselves in the foot with this feature if they really want. They just have to work a bit harder for it.
> The JVM's optimized code from programmers? Plausible, but aren't there already many cases where things get deoptimized based on run-time state changes?
This is not a good thing because interpreted mode is terribly slow. The JIT exists to make Java fast, and developers should not made this harder than necessary.
> It feels like someone just said "final means final!" without really thinking about the purpose of a JVM. Will there be a proposal to enforce checked exceptions, too?
Do people really write `final` and are OK being aware that the field's value could still change after all?
Checked exceptions are already enforced. If you mean changing all exceptions to be checked: no, that would be a catastrophic backwards compatibility break, with no good upside.
> Do people really write `final` and are OK being aware that the field's value could still change after all?
The converse: people really write `field.setAccessible(true)` and are OK being aware that they are breaking another programmer's assumptions. That's the point of `field.setAccessible(true)` existing at all. It's monkey-patching.
Otherwise you might as well just delete the method and throw a `NoSuchMethodError` when someone calls it - nobody is calling `setAccessible(false)`
I have some experience hacking on Java Minecraft. Minecraft's code is what it is - take it or leave it. The more stuff you can do without modifying that code, the simpler the overall system is. If you can set a field with reflection then you don't need to modify that class to make the field public or non-final. In other words, monkey-patching. (Newer frameworks support more modification to Minecraft's own code with less effort, though.)
> This is not a good thing because interpreted mode is terribly slow. The JIT exists to make Java fast, and developers should not made this harder than necessary.
And it does that by being smart. It makes assumptions, compiles code given those assumptions, and recompiles it if they actually do not hold. For example, I expect that a method with a List parameter is most likely only ever called with one implementation of List, and the JVM knows this and will compile the method as if the parameter is ArrayList, and will compile the method for the specific implementation it sees in the first few calls, with a bail-out check forcing the method to be recompiled if it's ever not that implementation.
And if the JVM never sees a subclass of a certain class, it can statically dispatch all calls to references of that type, as if the class were final, even if it isn't marked final.
And, likewise, if the JVM never sees a write instruction to a certain field, except once in the constructor, it should be able to treat it as if the field were final, and avoid reloading it after method calls. If it loads a class with an instruction that writes that field, it has to recompile all those methods.
The excemptions outlined in the JEP still allow people to do pretty much whatever they want as granular as they want. They can even wholesale revert to the old behavior. I really don't see the issue.
> And, likewise, if the JVM never sees a write instruction to a certain field, except once in the constructor, it should be able to treat it as if the field were final, and avoid reloading it after method calls. If it loads a class with an instruction that writes that field, it has to recompile all those methods.
Right now, many opportunities for this optimization cannot be used because `final` for non-static fields cannot be relied upon. If such a field modification happens, then it's far more difficult to locate all the code that is the result of constant propagation from that field's original value. The impact of changes in the other scenarios is quite limited in comparison.
> None of this should be news to the JVM engineers.
I know how JIT compilers work, and the OpenJDK team knows as well of course. Which is exactly why they pursue this change. Deoptimizing and recompiling simply sucks for performance because this is time the application could spend on far better things.
Of course they can, and it makes a lot of sense if they contain configuration settings or things like that. An instance might be held in a static final variable, and that reference can be inlined, but it's data can't unless it's an instance of a record or a hidden class, since for those classes final already means final.
That security model was obsolete and didn't fulfill its original purpose anymore. Most applications have never enabled it.
> Programmers from their own mistakes? That's fine, but this is about cases where they set the "I really mean it and this isn't a mistake" flag.
Not at all, the vast majority of code using this feature is part of libraries. Application developers are often not aware that this even happens. Anyway, it will also in the future be possible for developers to shoot themselves in the foot with this feature if they really want. They just have to work a bit harder for it.
> The JVM's optimized code from programmers? Plausible, but aren't there already many cases where things get deoptimized based on run-time state changes?
This is not a good thing because interpreted mode is terribly slow. The JIT exists to make Java fast, and developers should not made this harder than necessary.
> It feels like someone just said "final means final!" without really thinking about the purpose of a JVM. Will there be a proposal to enforce checked exceptions, too?
Do people really write `final` and are OK being aware that the field's value could still change after all?
Checked exceptions are already enforced. If you mean changing all exceptions to be checked: no, that would be a catastrophic backwards compatibility break, with no good upside.