Abarbeitungsreihenfolge Anonyme Klassen

Werniman

Mitglied
Hallo,
ich bin gerade dabei, die Video2Brain Tutorials "Java lernen Teil 3 - Generische Programmierung, Datenströme und Datums/Zeitberechnung" durchzu arbeiten und hänge mal wieder am Thema Anonyme Klassen. Genauergesagt weiß ich noch nicht, win welcher Reihenfolge diese eigentlich abgearbeitet werden.
Im Projekt soll einfach nur ein BMI errechnet werden. Dazu wurden folgende Klassen angelegt (die Striche sind nur zur optischen Trennung,wo eine neue Datei anfängt):


Java:
public interface BMIRechner<U, V> {
    public U rechne(V v);}

------------------------------------
public class BMIKoerper<E, F> {
    private E e;
    private F f;
....[hier kommen noch die ganzen Getter/Setter-Sachen]
    }

------------------------------------

public class AppAnonym {
    public static void main(String[] args) {
        new AppAnonym();
    }
    public AppAnonym() {
        BMIRechner<Double, BMIKoerper<Double, Double>> rechner = new BMIRechner<Double, BMIKoerper<Double, Double>>() {
            @Override
            public Double rechne(BMIKoerper<Double, Double> v) {
                return v.getF() / (v.getE() * v.getE());
            }
        };
        BMIKoerper<Double, Double> koerper = new BMIKoerper<Double, Double>();
        try (Scanner scanner = new Scanner(System.in)) {
            System.out.print("Groesse ? ");
            koerper.setE(scanner.nextDouble());
            System.out.print("Gewicht ? ");
            koerper.setF(scanner.nextDouble());
            System.out.printf("BMI-Wert: %.1f", rechner.rechne(koerper));
        }
    }
}

Meine Frage: in welcher Reihenfolge wird das eigentlich abgearbeitet ? Speziell denke ich dabei an den Konstruktor von AppAnonym, genauergesagt um die Zeile, wo das BMIRechner-Objekt erzeugt wird. Dort steht in den Generics "BMIKoerper<Double,Double>" drin. Heißt das, dass Java beim erzeugen von BMI-Rechner erstmal einen kurzen Abstecker zu BMIKoerper macht und den anlegt,bevor es den BMI-Rechner fertigbaut ?
 
Dabei handelt es sich doch nur um einen Parameter. Da wird nichts erzeugt. Das tatsächlich erzeugte BMIKoerper<> Objekt wird erst beim Aufruf der Methode rechne() übergeben.
 
Heißt das, dass Java beim erzeugen von BMI-Rechner erstmal einen kurzen Abstecker zu BMIKoerper macht und den anlegt,bevor es den BMI-Rechner fertigbaut ?
Das sind Typparameter, die der Typsicherheit zur Übersetzungszeit dienen.

Wenn Du z. B. eine List verwendest, ohne einen Typparameter anzugeben, geht der Compiler davon aus, dass die Elemente vom Typ Object sind. Wie Du bestimmt weißt, sind alle Klassen von Object abgeleitet, d. h. Du kannst zur Liste Objekte beliebiger Klassen (auch gemischt) hinzufügen.

List#get() liefert in dem Fall einfach ein Objekt vom Typ Object, so dass Du auf den gewünschten Typ casten musst. Der Cast wird zur Laufzeit überprüft, so dass Fehler erst dann erkannt werden.

Beispiel:
Java:
import java.util.List;
import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("Test"); // String-Objekt hinzufügen
        Object obj = list.get(0); // get liefert ein Object, das die String-Methoden nicht kennt, daher
        String s = (String) obj; // dem Compiler mitteilen, dass es sich um einen String handelt
        if (s.isEmpty()) {  // String-Methoden verwenden
        }
    }
}

Das Beispiel kann fehlerfrei übersetzt und ausgeführt werden. Wenn Du list.add("Test"); durch z. B. list.add(new ArrayList()); ersetzt, kann der Code immer noch übersetzt werden. Zur Laufzeit erhältst Du aber eine ClassCastException.

Durch die Verwendung von Typparameter stellt der Compiler von vornherein sicher, dass nur kompatible Typen in der Liste landen. Würde man die Liste also mit List<String> list deklarieren, würde list.add(new ArrayList()); zu einem Compilerfehler führen. Außerdem wird der Code lesbarer, weil die nervigen Casts wegfallen.
 

Zurück
Oben