> 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.
None of this should be news to the JVM engineers.