Tener problemas para escribir funciones genéricas en Java

I'm trying to create a function that uses the value of ? for the type of a variable's type. How would I write this?

interface MyInterface<TYPE extends Collection> {
    TYPE getResult();
    void useResult( TYPE inResult );
}

class SomeOtherClass {
    static void moveObject( MyInterface<?> inObj ) {
        //I'm using the wrong syntax on the next line, but I'm not sure
        // what I should use here.
        <?> result =  inObj.getResult();
        inObj.useResult(result);
    }
}

preguntado el 08 de noviembre de 11 a las 10:11

5 Respuestas

Agrega una <T> entre static y void:

import java.util.List;

interface MyInterface<T extends List<Integer>> {
    T getResult();

    void useResult(T inResult);
}

class SomeOtherClass {
    static <T extends List<Integer>> void moveObject(MyInterface<T> inObj) {
        T result = inObj.getResult();
        inObj.useResult(result);
    }
}

respondido 08 nov., 11:14

Are you able to add an explanation ? - Rico

What would you like me to explain? - JesperE

I know the <T extends List<Integer>> isn't a return type, but for people like me who have never had a need to go beyond quite basic generics, it would help me understand what it is :) - Rico

<T extends List<Integer>> declaration specifies that the given method is a generic method which takes one type parameter, T, which is restricted to be a subclass of List<Integer>. If you don't need any restriction on T at all, you can write <T>. But in most practical cases you will need to have some bound on T in order to be able to do anything with it. - JesperE

I believe the following should work (untested, and out of memory):

class SomeOtherClass {
    static <T extends Collection> void moveObject( MyInterface<T> inObj ) {
        T result =  inObj.getResult();
        inObj.useResult(result);
    }
}

respondido 08 nov., 11:14

Pruébalo así ...

static <T> void moveObject(MyInterface<T> inObj) {
    T result = inObj.getResult();
    ...
}

respondido 08 nov., 11:14

class SomeOtherClass {
    static <T> void moveObject( MyInterface<T> inObj ) {
        T result =  inObj.getResult();
        inObj.useResult(result);
    }
}

respondido 08 nov., 11:14

Like others have said, the only way for it to remember that the thing you get out is the right type to put back in is to introduce a type variable. Once a thing becomes a ? it loses all sense of what that ? is. (A common example for this same issue is if you tried to write a utility method to swap two elements in a List.)

class SomeOtherClass {
    static <T extends Collection> void moveObject( MyInterface<T> inObj ) {
        T result =  inObj.getResult();
        inObj.useResult(result);
    }
}

However, you might complain that this forces you to change the signature of the method, publicly exposing an unnecessary implementation detail, and causing problems if you are overriding an inherited method that does not have the type variable. Because, since T is used only once in the argument, it debemos be possible to change it to ?. You can do this cleanly using a (private) helper method, due to the way capturing works:

class SomeOtherClass {
    static void moveObject( MyInterface<?> inObj ) {
        moveObjectHelper(inObj);
    }
    private static <T extends Collection> void moveObjectHelper( MyInterface<T> inObj ) {
        T result =  inObj.getResult();
        inObj.useResult(result);
    }
}

respondido 09 nov., 11:00

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.