Collections Generics: Typ wird nicht erkannt

Javinner

Top Contributor
Hallo an alle,

habe folgendes Problem: Kann ein Integer einem Integer nicht zuweisen.
Warum ist es so? Die Konsolenausgabe bestätigt doch, dass die beiden Taschen der
Person eine Variable von Typ Integer speichern, also auch von Typ Integer sind?!
Stehe ziemlich auf dem Schlauch..


Java:
public class JIAEI_Generics
{

    public static void main(String[] args)
    {
        Person person = new Person();
        Pocket<Integer> pocketA = new Pocket<>(20);
        Pocket<Integer> pocketB = new Pocket<>(2);
        person.setLeftPocket(pocketA);
        person.setRightPocket(pocketB);
        System.out.println("Links: " + person.getLeftPocket().getValue().getClass()); 
        System.out.println("Rechts: " + person.getRightPocket().getValue().getClass());
        /** Konsolenausgabe */
        Links: class java.lang.Integer
        Rechts: class java.lang.Integer

        int links = person.getLeftPocket().getValue(); //Object cannot be converted to int
        int rechts = person.getRightPocket().getValue(); //Object cannot be converted to int
    }

}
Java:
public class Person
{

    private String name;
    private Pocket leftPocket;
    private Pocket rightPocket;

    public String getName()
    {
        return name;
    }

    public Pocket getLeftPocket()
    {
        return leftPocket;
    }

    public Pocket getRightPocket()
    {
        return rightPocket;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public void setLeftPocket(Pocket leftPocket)
    {
        this.leftPocket = leftPocket;
    }

    public void setRightPocket(Pocket rightPocket)
    {
        this.rightPocket = rightPocket;
    }

}
Java:
public class Pocket<T>
{

    private T value;

    public Pocket()
    {
    }

    protected Pocket(T value)
    {
        this.value = value;
    }

    public T getValue()
    {
        return value;
    }

    public void setValue(T value)
    {
        this.value = value;
    }

    protected boolean isEmpty()
    {
        return this.value == null;
    }

    protected void empty()
    {
        this.value = null;
    }

}

edit: wenn ich es nach Int caste, dann geht es. Jedoch dachte ich, dass hier Integer automatisch mitübernommen wird. Wo denke ich falsch?

int links = (int) person.getLeftPocket().getValue();
int rechts = (int) person.getRightPocket().getValue();
 
Problem ist dass du bei den beiden Pocket-Objekten in der Personen-Klasse keine Generics angegeben hast.
Wenn du dort die Pockets auch bspw zu einem Pocket<Integer> machst und die Setter dementsprechend abänderst sollte der Fehler verschwinden.
 
@Robat
Danke für Antwort!
Habe folgende Änderungen vorgenommen:
Java:
public class Person
{

    private String name;
    private Pocket<?> leftPocket;
    private Pocket<?> rightPocket;

    public String getName()
    {
        return name;
    }

    public Pocket getLeftPocket()
    {
        return leftPocket;
    }

    public Pocket getRightPocket()
    {
        return rightPocket;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public void setLeftPocket(Pocket<?> leftPocket)
    {
        this.leftPocket = leftPocket;
    }

    public void setRightPocket(Pocket<?> rightPocket)
    {
        this.rightPocket = rightPocket;
    }

}
leider ohne positiven Ergebnis, kann die Werte den Int-Variablen ohne vorher auf int zu casten, nicht zuweisen. Hm..
 
Das kann so auch nicht funktionieren.
Mit der Wildcard sagst du dem Compiler, dass da ein Typ kommt den du nicht kennst. Daher kann der Compiler auch nicht garantieren das es in ein Int konvertiert werden kann.
Der einzige Weg der mir spontan einfällt ist explizit anzugeben dass es sich um ein Pocket<Integer> handelt.

Du könntest natürlich auch die Person-Klasse generisch machen (wäre aber meiner Meinung nach aber keine bevorzugte Variante.)
 
Geplant war es so, dass die Person zwei Taschen hat und man diese nach belieben füllen kann. Sprich Integer rein, dann wieder Löschen, mit String füllen usw. Habe schon überlegt, dass man die Klasse Person auch typisieren könnte, so ist es aber nicht der Sinn des ganzen.

Vielen Dank für die Antwort, werde jetzt noch als Nachtlektüre die
Insel lesen (Junge, ist es ein dicker Schnitzel).
Schönen Abend.
 
Geplant war es so, dass die Person zwei Taschen hat und man diese nach belieben füllen kann. Sprich Integer rein, dann wieder Löschen, mit String füllen usw. Habe schon überlegt, dass man die Klasse Person auch typisieren könnte, so ist es aber nicht der Sinn des ganzen.
Mit Generics nicht möglich, dafür müsste der Typ Object sein, und man müsste benötigt Typ-Informationen uU händisch mitschleppen
 
Ich verstehe eins nicht:
- wenn ich die Klasse abfrage, dann ist diese vom Typ Integer, bzw, der Rückgabewert der Variablen value, dann muss doch automatisch die Klasse von Typ Integer sein. Ebenso ist es möglich, die Werte wieder zu löschen und ganz neue zu setzen. Warum kann ich aber nicht ohne vorher zu casten, die Werte, welche vom gleichen Typ sind, nicht übertragen, das leuchtet mir nicht ein.
Java:
public class JIAEI_Generics
{

    public static void main(String[] args)
    {
        Person person = new Person();
        Pocket<Integer> pocketInteger = new Pocket<>(20);
        Pocket<String> pocketString = new Pocket<>("String");

        System.out.println("--------------------------------------Füllen der Taschen");
        person.setLeftPocket(pocketInteger);
        person.setRightPocket(pocketString);

        System.out.println("--------------------------------------Abfrage: leere Taschen?");
        System.out.println("Links: " + person.getLeftPocket().isEmpty());
        System.out.println("Rechts: " + person.getRightPocket().isEmpty());

        System.out.println("--------------------------------------Abfrage: Klasse");
        System.out.println("Links: " + person.getLeftPocket().getValue().getClass());
        System.out.println("Rechts: " + person.getRightPocket().getValue().getClass());

        System.out.println("--------------------------------------Taschen leer");
        person.getLeftPocket().empty();
        person.getRightPocket().empty();

        System.out.println("--------------------------------------Abfrage: leere Taschen?");
        System.out.println("Links: " + person.getLeftPocket().isEmpty());
        System.out.println("Rechts: " + person.getRightPocket().isEmpty());

        System.out.println("--------------------------------------Füllen der linken Tasche");
        
        Pocket<Double> pocketDouble = new Pocket<>(123.451);
        person.setLeftPocket(pocketDouble);

        System.out.println("--------------------------------------Abfrage: linke Tasche leer?");
        System.out.println("Links: " + person.getLeftPocket().isEmpty());
        System.out.println("--------------------------------------Abfrage: linke Tasche Klasse");
        System.out.println("Links: " + person.getLeftPocket().getValue().getClass());

    }

}
/** Konsolenausgabe */
run:
--------------------------------------Füllen der Taschen
--------------------------------------Abfrage: leere Taschen?
Links: false
Rechts: false
--------------------------------------Abfrage: Klasse
Links: class java.lang.Integer
Rechts: class java.lang.String
--------------------------------------Taschen leer
--------------------------------------Abfrage: leere Taschen?
Links: true
Rechts: true
--------------------------------------Füllen der linken Tasche
--------------------------------------Abfrage: linke Tasche leer?
Links: false
--------------------------------------Abfrage: linke Tasche Klasse
Links: class java.lang.Double
BUILD SUCCESSFUL (total time: 0 seconds)
 
wenn ich die Klasse abfrage, dann ist diese vom Typ Integer, bzw, der Rückgabewert der Variablen value, dann muss doch automatisch die Klasse von Typ Integer sein. Ebenso ist es möglich, die Werte wieder zu löschen und ganz neue zu setzen.
Richtig - zur Laufzeit liegt da ein Integer drin.

Warum kann ich aber nicht ohne vorher zu casten, die Werte, welche vom gleichen Typ sind, nicht übertragen, das leuchtet mir nicht ein.
Das kannst du mit Generics schon, wenn du trotzdem casten musst, machst du wahrscheinlich was falsch.
Kommt in deinem Code aber nicht vor.
 

Zurück
Oben