Таким образом, вы можете изменить статическое конечное поле, и если вы посмотрите на значение, используя отражение, оно будет изменено. Проблема, с которой вы столкнулись, заключается в том, что компилятор выполняет одну-единственную оптимизацию, которая заключается в том, что встроенные константы знают во время компиляции. Это означает, что значение может быть изменено, однако места, где используется константа, не изменены.
Способ обойти это - использовать метод-обертку, чтобы «запутать» компилятор, чтобы избежать необходимости менять способ использования константы.
public static final long RECV_TIMEOUT = runtime(180000L);
public static final <T> T runtime(T t) { return t; }