Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B38FGKKam5SCGgwgduVAh3
34 lines
1.4 KiB
Java
34 lines
1.4 KiB
Java
import java.lang.reflect.Field;
|
|
|
|
/**
|
|
* JEP 500 (Java 26): "Prepare to Make Final Mean Final". Deep reflection on a final field
|
|
* (Field.setAccessible(true) followed by Field.setInt) used to work silently. On 26 it works but
|
|
* warns once; a future release will deny it unless you opt in.
|
|
*
|
|
* The same file is run five ways by scripts/recap26.sh; the transcript is docs/output/70-final-field-mutation.txt.
|
|
* Chapter: docs/11-recap-26.md
|
|
*/
|
|
public class FinalFieldMutation {
|
|
static class Config {
|
|
private final int port = 8080;
|
|
int port() { return port; }
|
|
}
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
Config c = new Config();
|
|
Field f = Config.class.getDeclaredField("port");
|
|
f.setAccessible(true);
|
|
try {
|
|
f.setInt(c, 9090);
|
|
} catch (IllegalAccessException e) {
|
|
System.out.println("setInt refused : " + e.getMessage());
|
|
return;
|
|
}
|
|
// The field reads 9090 but port() still says 8080: 'final int port = 8080' is a constant variable, so javac
|
|
// copied the literal 8080 into port() at compile time. Nothing you write to the field can reach that copy.
|
|
// That silent disagreement is the reason the platform wants this to stop, not a hypothetical.
|
|
System.out.println("field reads : " + f.getInt(c));
|
|
System.out.println("port() returns : " + c.port());
|
|
}
|
|
}
|