Reglas de sobrecarga de Java

Encontré dos preguntas de sobrecarga recientemente para las que no puedo encontrar una respuesta y no tengo un entorno Java para ejecutar algún código de prueba. Espero que alguien pueda ayudarme armando una lista de todas las reglas que siguen los compiladores Java para sobrecargar o indicándome alternativamente una lista que ya existe.

Primero, cuando dos métodos difieren solo por un parámetro varargs final, ¿en qué circunstancias se llama a cada uno y puedes llamar al método varargs sin ningún argumento?

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?

Segunda pregunta, cuando dos métodos difieren según los tipos heredados el uno del otro, ¿cuál es el llamado? Espero que se llame a la versión más derivada, y que el casting tenga permitido llamar a la otra.

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?

Estos son los dos ejemplos, pero como lector de código prefiero una lista canónica de las reglas ordenadas exactas que se usan para resolver esto, ya que con frecuencia no tengo tiempo para configurar un entorno de compilación para verificar qué está haciendo el compilador.

Respuestas a la pregunta(2)

Su respuesta a la pregunta