Kleine Generics Aufgabe aus einer Prüfung... wie ist das gemeint?

vandread

Aktives Mitglied
Hallo Leute,

ich schreib am Freitag eine Prüfung und bei den Übungen ist mir jetzt eine Aufgabe in die Finger gekommen wo ich erst mal 5 mal lesen musste um zu verstehen was der gute Professor da eigentlich will...

Um ehrlich zu sein bin ich mir nicht sicher was er da will 🙂

Hier die Originale Aufgabe: https://dl.dropbox.com/u/14115692/Aufgabe.pdf

Aufgabentext:
Die Klasse GenUtils enthält die Klassenmethode addAndDisplay(), die ein Objekt vom generischen Typen T zu einer Arraylist<T> hinzufügt. Anschließend wird der Inhalt der Liste ausgegeben. Programmieren Sie die Methode addAndDisplay() aus.

In main() der Klasse TestGenUtils, schreiben Sie bitte einen Aufruf der Klassenmethode addAndDisplay(), der einen Integer mit dem Wert 5 zu einer Arraylist hinzufügt (10 min)


Soweit so gut... Ich möchte jetzt anmerken dass bei den Aufgaben immer platz gelassen wird wenn man irgendwo was ergänzen muss, auch oben bei den Klassennamen usw... (Siehe PDF)

Ich weiß nicht ob ich die Aufgabe richtig verstanden habe aber meine Lösung sieht wie folgt aus:

Java:
public class GenUtils<T> {

    public void addAndDisplay(T element, ArrayList<T> list) {
        list.add(element);

        for (T e : list) {
            System.out.println(e);
        }
    }
}

Java:
public class TestGenUtils {

    public static void main(String[] args) {
        ArrayList<Integer> myList = new ArrayList<>();

        GenUtils<Integer> gu = new GenUtils<>();

        gu.addAndDisplay(5, myList);
    }
}

Es gibt da nur ein Problem... oben bei "class GenUtils" wurde kein Platz gelassen um eine Typvariable reinzuschreiben, also muss wohl meine Lösung falsch sein... Außerdem finde ich das auch sehr komisch... Vielleicht denke ich ja auch nur falsch...
Außerdem ist in der Aufgabe nur von addAndDisplay() die rede als würde die Methode keine Übergabeparameter besitzen...

Deswegen wollte ich mal wissen was ihr dazu sagt...
 
Es wird verlangt dass
Code:
addAndDisplay()
eine Klassenmethode ist. Das was du gemacht hast sind so gesehen Instanz-Methoden.

Das Schlüsselwort, dass verwendet werden soll heißt static.
Und static Methoden können auch Parametrisiert werden, allerdings nicht über die Klasse.

Java:
import java.util.*;

public class GenUtils {

  public static <T> void addAndDisplay(T element, Collection<T> list){
    list.add(element);
    for(T t:list){
      System.out.println(t);
    }
  }

}

Java:
import java.util.*;
public class TestGenUtils{

  public static void main(String[] args){
    List<Integer> list = new ArrayList<>();
    GenUtils.addAndDisplay(5, list);
  }
}

Statt die Interface Collection und List, gutem Programmierstil entsprechend, kann man der Aufgabenstellung entsprechend auch direkt gegen ArrayList programmieren.

In der Aufgabenstellung wird auch von main(), anstatt wie vorgegeben main(String[] args) geschrieben, deshalb gehe ich davon aus, daß bei addAndDisplay() auch die Argumente weggelassen wurden, um Konsistent zu bleiben.
 
Zuletzt bearbeitet von einem Moderator:
Die Lösung ist korrekt, aber...

Es wird verlangt dass
Code:
addAndDisplay()
eine Klassenmethode ist. Das Und static Methoden können auch parametrisiert werden, allerdings nicht über die Klasse.

So weit so gut, aber das geht genauso mit nicht-statischen Methoden.

Es ist verwirrend zu sagen, dass eine Methode "über die Klasse parametrisiert" wird. Entweder die Klasse ist parametrisiert (dann können die entsprechenden Parameter auch von der (nicht-statischen) Methode benutzt werden), oder die Methode selbst ist parametrisiert, oder beides.
 
Vielen Dank für die Hilfe! 🙂

Nur eine kleine Frage...

Und static Methoden können auch Parametrisiert werden, allerdings nicht über die Klasse.

Wie darf ich das Verstehen?
Also ein kleines Beispiel...

Java:
public class Foo {
 
  public static <T> T bla(T val){
    return val;
    }
  }
 
}

Das geht so okay...
Die Methode ist static und wurde selber parametrisiert...

Was aber wenn ich sowas hier mache?

Java:
public class Foo <T> {

 public void bla(T val){
    System.out.println(T);
    }
  }

  public static <T> T bla(T val){
    return val;
    }
  }
 
}

Das dürfte ja nach deiner Aussage nicht gehen...
Logisch kann ich mir das nur so erklären dass wenn ich noch keine Instanzerzeugt habe die static Methode gar nicht wissen kann für das T steht... daher müsste es wohl so aussehen:

Java:
public class Foo <T>{

 public void bla(T val){
    System.out.println(T);
    }
  }

  public static <X> X bla(X val){
    return val;
    }
  }
 
}

Die Parameter müssen unterschiedlich sein?!
 
Java:
class My<A> {

   // verwendet das A aus der Klasse
   public A getA(){ return null; }

   // ein "neues" A wird definiert, dieses neue A entspricht NICHT dem A der Klasse/des Objekts
   // Die IDE meldet auch als Warning: "the parameter type A is hiding the type A"
   public <A> A getAnother(){ return null; }
}

Der Code sollte es erklären.
 
Was aber wenn ich sowas hier mache?

Java:
public class Foo <T> {

 public void bla(T val){
    System.out.println(T);
    }
  }

  public static <T> T bla(T val){
    return val;
    }
  }
 
}

Das dürfte ja nach deiner Aussage nicht gehen...

Doch, nur ist das T, das die Methode verwendet, ein anderes als das der Instanz. Allerdings vermute ich, dass der Compiler meckert, weil die beiten Ts dieselbe Erasure [c]Object[/c] haben, und damit die beiden Methoden [c]bla[/c] ins Gehege kommen. Müsste man mal ausprobieren. Aber wenn die Methoden unterschiedlich heißen, sollte es auf jeden Fall gehen.

Logisch kann ich mir das nur so erklären dass wenn ich noch keine Instanzerzeugt habe die static Methode gar nicht wissen kann für das T steht... daher müsste es wohl so aussehen:

Java:
public class Foo <T>{

 public void bla(T val){
    System.out.println(T);
    }
  }

  public static <X> X bla(X val){
    return val;
    }
  }
 
}

Die Parameter müssen unterschiedlich sein?!

Nein, müssen sie nicht. Wie gesagt weiß ich jetzt aus dem Hut nicht genau, ob eine der beiden Methoden umbenannt werden müsste, aber prinzipiell kannst du ein "Klassen-T" und ein völlig unabhängiges "Methoden-T" haben. Selbst ohne
Code:
static
würde das funktionieren:

Java:
public class Foo <T>{

 public void bla1(T val){
    System.out.println(T);
    }
  }

  public <T> T bla2(T val){
      return val;
    }
  }
 
}

Ob das eine gute Idee ist, sein einmal dahingestellt.
 

Zurück
Oben