Правила перегрузки Java

Недавно я натолкнулся на два перегруженных вопроса, на которые я не могу найти ответ, и у меня нет среды Java для запуска некоторого тестового кода. Я надеюсь, что кто-то может помочь мне, составив список всех правил, которым следуют java-компиляторы, для перегрузки или поочередно указывать мне на список, который уже существует.

Во-первых, когда два метода отличаются только конечным параметром varargs, при каких обстоятельствах каждый из них вызывается и можете ли вы вызвать метод varargs без аргументов?

private void f(int a) { /* ... */ }
private void f(int a, int... b) { /* ... */ }

f(12); // calls the former? I would expect it to
f(12, (int[])null); // calls latter, but passes null for b? 
  // Can I force the compiler to call the second method in the same fashion
  // as would happen if the first method didn't exist?

Второй вопрос: когда два метода различаются по типам, унаследованным друг от друга, который вызывается? Я ожидаю, что будет вызываться самая производная версия, а при кастинге - другая.

interface A {}
class B implements A {}
class C implements A {}

private void f(A a) {}
private void f(B b) {}

f(new C()); // calls the first method
f(new B()); // calls the second method?
f((A)(new B()); // calls the first method using a B object?

Это два примера, но в качестве устройства для чтения кода я предпочел бы канонический список точно упорядоченных правил, используемых для решения этой проблемы, поскольку у меня часто нет времени настраивать среду сборки для проверки того, что делает компилятор.

Ответы на вопрос(2)

Ваш ответ на вопрос