Warum kann ich zum Füllen eines Arrays mit Objekten keine for each Schleife verwenden?



  • Ich habe folgende drei Klassen:

    package test;
    
    public class Test {
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            OuterClass myClass = new OuterClass();
            myClass.setArray(5);
            System.out.println("Anzahl = " + myClass.getArrayAnzahl());
            myClass.ausgabe();
        }
    
    }
    
    package test;
    
    public class OuterClass {
        InnerClass[] array;
    
        public int getArrayAnzahl() {
            return array.length;
        }
    
        public void setArray(int anzahl) {
            this.array = new InnerClass[anzahl];
    // Variante A geht nicht:
    //        for (InnerClass  array: this.array){
    //            array = new InnerClass();
    //        }
    
    // Variante B geht:
            for (int i = 0; i < this.array.length; i++){
                this.array[i] = new InnerClass();
            }
        }
    
        public void ausgabe(){
            for (InnerClass array: this.array){
                System.out.println(array.value);
            }
    
        }
    
        protected static class InnerClass{
            public int value;
    
            public InnerClass(){
            }
        }
    }
    

    In der Methode setArray definiere ich wieviele Objekte das Array in der OuterClass haben soll und in der darauf folgende Schleife initalisiere ich das
    Array mit Objekten vom Typ InnerClass, damit mir das Programm beim Aufruf von ausgabe() keine Exception wegen einem Zugriff auf ein nicht initalisierten Array wirft.

    Bei Variante A versuche ich das Initialisieren mit einer for each Schleife, aber das funktioniert nicht, da das array der OuterClass weiterhin mit null Objekten initalisiert bleibt.

    Verwende ich dagegen Variante B geht es.

    Frage:
    Warum?

    Kann es sein, dass für die for each Schleife eine Kopie vom Typ des Objekts erzeugt wird, anstatt auf das array zu referenzieren?



  • Dann noch eine weitere Frage.

    Wie dem ein oder anderen vielleicht aufgefallen ist, ist die InnerClass mit dem Bezeichner static gekennzeichnet und somit statisch, also eine Klassenvariable.

    Wieso kann ich dann von dieser Objekte erzeugen, die unterschiedlich sein können?
    Value kann hier verschiedene Werte tragen, obwohl das ja eigentlich eine Klassenvariable ist und somit Value für alle an das Array übergebene Objekte identisch sein müsste.
    Dies ist aber nicht der Fall, wie ich gerade feststellen musste.
    Zum Testen einfach jedem an das Array übergebenen Objekt einen anderen Wert für Value geben und dann den Value aller Objekte ausgeben.

    Korrekt wäre natürlich, die InnerClass ohne static zu einer nichtstatischen Klasse zu machen, aber das es auch so geht, ist schon seltsam.
    Zu erwarten wäre eigentlich, wenn value z.B. den Wert 7 bekommt, dass alle an das array übergebene Objekte in dem Member value die gleiche Zahl haben.
    Dem ist seltsamerweise aber nicht so.



  • Nachtrag:

    Nur wenn ich

    public int value;

    zu einem

    public static int value;

    mache, sind alle Werte über da gesamte Array identisch.
    Da stellt sich dann die Frage, wieso ich überhaupt von einer statischen Klasse Objekte erzeugen kann.


  • Mod

    for (InnerClass  array: this.array)
    

    array ist eine Referenz auf die Objekte in this.array. Wenn du diese irgendwo anders hin umbiegst, interessiert das this.array nicht.

    Weiterhin ist es relativ sinnlos, dies überhaupt zu wollen. Eine Zeile vorher hast du schließlich schon eine Reihe von Objekten angelegt:

    this.array = new InnerClass[anzahl];
    

    Das lässt this.array doch bereits auf eine Sammlung von anzahl InnerClass-Objekten verweisen. Diese dann nochmals einzeln erstellen zu wollen ist nicht nur unnötig, es macht überhaupt keinen Sinn. Das solltest du doch bereits da dran merken, dass du über die Objekte iterierst. Wieso solltest du sie dann noch einmal erzeugen, sie sind doch offensichtlich schon da!

    Wie dem ein oder anderen vielleicht aufgefallen ist, ist die InnerClass mit dem Bezeichner static gekennzeichnet und somit statisch, also eine Klassenvariable.

    Deine Beschreibung ist ungefähr das Gegenteil von dem, was static hier bedeutet. Vielleicht solltest du mal googeln, was eine static nested class ausmacht.



  • SeppJ schrieb:

    Weiterhin ist es relativ sinnlos, dies überhaupt zu wollen. Eine Zeile vorher hast du schließlich schon eine Reihe von Objekten angelegt:

    this.array = new InnerClass[anzahl];
    

    Das lässt this.array doch bereits auf eine Sammlung von anzahl InnerClass-Objekten verweisen. Diese dann nochmals einzeln erstellen zu wollen ist nicht nur unnötig, es macht überhaupt keinen Sinn.

    Wenn dem so wäre, wär es schön.
    Aber versuch mal dem value einen jeden Objekts im Array einen Wert zu geben, wenn du nur
    this.array = new InnerClass[anzahl]

    drinstehen hast.
    Dann wirft dir die JVM eine null Pointer Exception, weil es die Objekte nicht gibt, wie der Debugger schnell aufzeigt.
    Deswegen habe ich diese Schleife überhaupt erst eingebaut.

    Das solltest du doch bereits da dran merken, dass du über die Objekte iterierst. Wieso solltest du sie dann noch einmal erzeugen, sie sind doch offensichtlich schon da!

    Nein, ich iteriere nur durch ein Array, dass auf Objekte referenzieren kann.
    Die Objekte gibt's aber noch nicht.

    Das ist ähnlich:

    Person per = new Person("Hans"); // Object ist vorhanden.
    Person per2; // Es gibt nur ne Referenz, aber noch kein Objekt.

    per.getName(); // geht
    per2.getName(); // geht nicht -> zeigt nämlich auf null

    Wie dem ein oder anderen vielleicht aufgefallen ist, ist die InnerClass mit dem Bezeichner static gekennzeichnet und somit statisch, also eine Klassenvariable.

    Deine Beschreibung ist ungefähr das Gegenteil von dem, was static hier bedeutet. Vielleicht solltest du mal googeln, was eine static nested class ausmacht.

    [/quote]
    Sag du es mir.


Anmelden zum Antworten