Статический метод через необъявленную переменную

Классика на «что выведет код»: статический метод вызывают через ссылку на объект, который даже не был инициализирован.

class Util { static void print() { System.out.println("static method"); } }

public class Main { public static void main(String[] args) { Util b; b.print(); } }

Кажется, что раз метод статический, компилятору должно быть всё равно — он всё равно резолвится по типу переменной, а не по значению ссылки. На рантайме так и есть: NPE тут не будет, даже если b останется null.

Но до рантайма дело не доходит. Javac проверяет definite assignment для каждой локальной переменной до любого её использования — и для статических вызовов через переменную тоже. b объявлена, но не инициализирована, значит использовать её как квалификатор нельзя.

Компилятор выдаст: variable b might not have been initialized. Если заменить на Util.print() — скомпилируется и напечатает static method без всяких NPE, потому что статический метод не трогает состояние объекта вообще.

Вывод, который стоит унести: вызов статического метода через переменную — это синтаксический сахар, компилятор всё равно требует, чтобы переменная была определена явно, даже когда её значение никогда не понадобится.

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки