Zasady przeciążania Java

Niedawno natknąłem się na dwa przeciążające pytania, na które nie mogę znaleźć odpowiedzi i nie mam środowiska java do uruchomienia kodu testowego. Mam nadzieję, że ktoś może mi pomóc, zbierając listę wszystkich reguł, które podążają kompilatory java, aby przeładować lub na przemian wskazywać mnie na już istniejącą listę.

Po pierwsze, gdy dwie metody różnią się tylko końcowym parametrem varargs, w jakich okolicznościach każdy z nich jest wywoływany i czy można wywołać metodę varargs bez żadnych argumentów?

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?

Drugie pytanie, kiedy dwie metody różnią się typami dziedziczonymi od siebie, które są wywoływane? Spodziewałbym się, że najbardziej wywodząca się wersja zostanie wywołana, a casting pozwoli na wywołanie drugiej.

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?

Są to dwa przykłady, ale jako czytnik kodu wolałbym kanoniczną listę dokładnych uporządkowanych reguł używanych do rozwiązania tego problemu, ponieważ często nie mam czasu na skonfigurowanie środowiska kompilacji, aby sprawdzić, co robi kompilator.

questionAnswers(2)

yourAnswerToTheQuestion