¿Por qué este uso de genéricos no genera una excepción de tiempo de ejecución o tiempo de compilación?

Tengo un método en una clase que tiene un tipo de retorno especificado mediante el uso de un genérico.

public class SomeMain {

  public static void main(String[] args) {

    Foo<Integer> foo = new Foo<Integer>();
    System.out.println(foo.getFoo()); // Works, prints out "Foo"

  }

  public static class Foo<E>  {
    public E getFoo() {
      return (E) "Foo";
    }
  }
}

Con el tipo de retorno genérico, supuse que el retorno en el ejemplo anterior se evaluaría para:

return (Integer) "Foo";  // Inconvertible types !!!

En lugar de unString se devuelve e imprime correctamente.

Obtengo un error de compilación si cambio la llamada para que sea:

String fooString = foo.getFoo(); // Compile error, incompatible types found
System.out.println(fooString);

¿Qué me falta para ayudarme a entender qué está pasando aquí y por qué la versión original no resultó en un error de compilación?

Respuestas a la pregunta(3)

Su respuesta a la pregunta