System.out объявляется как public static final PrintStream out.
Но вы можете вызвать System.setOut(), чтобы переназначить его.
А? Как это возможно, если он final?
(то же самое относится к System.in и System.err)
И что еще более важно, если вы можете мутировать публичные статические конечные поля, что это означает в отношении гарантий (если таковые имеются), которые final дает вам? (Я никогда не понимал и не ожидал, что System.in/out/err будет вести себя как переменные final)