Warum absorbiert ein List <type> ein nicht typisiertes Element in der Kompilierungs- und Ausführungszeit?

Ich habe diese Demo, für die ich keine bestimmte Lösung mit einer neu gezeichneten Architektur benötige, aber ich verstehe nur, warum sich das so verhält und was mir fehlt, um es zu vermeiden. Ich frage mich warum:

Der Compiler ermöglicht das Einfügen eines Elements, das nicht dem Typ der Liste entspricht, in die Liste

Die ClassCast-Ausnahme wird ausgelöst, wenn versucht wird, das Element abzurufen, anstatt es zu pushen

import Test.*; //Inner classes
import java.util.List;
import java.util.ArrayList;

public class Test<E extends Object> {

    private List<E> list = new ArrayList<E>();
    public Test() {}

    public static void main(String[] args) {
        Test<String> a = new Test<String>();
        a.addElement(new String());
        a.addElement(new Integer(0)); // No complain in comp/run-time, I dont understand why CastException is not thrown here
        String class1 = a.getElement(0); 
        String class2 = a.getElement(1); //No complain in comp but ClassCastException: Integer cannot be cast to String
        //Integer class3 = a.getElement(1); //Compilation error
    }

    public void addElement (Object node) { list.add((E) node); } //No complain in comp/run-time
    public E getElement(int index)       { return list.get(index); }
}

Was könnte eine Lösung sein? Beachten Sie die Zeile addElement, in der ich anstelle von Typ E eine SuperClass übergeben muss. Dies ist für meine Architektur erforderlich, dies ist nur eine einfache Demo. Aber auf jeden Fall sollte das Casting auf Typ E wie gewünscht funktionieren und zur Laufzeit eine CastExeption auslösen, oder?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage