Patrick M
Patrick M

Reputation: 1086

Having trouble writing generic function in 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);
    }
}

Upvotes: 0

Views: 100

Answers (5)

newacct
newacct

Reputation: 122489

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 should 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);
    }
}

Upvotes: 0

Janoz
Janoz

Reputation: 953

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

Upvotes: 0

Karl
Karl

Reputation: 1233

try it like this...

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

Upvotes: 0

Romain
Romain

Reputation: 12819

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);
    }
}

Upvotes: 0

JesperE
JesperE

Reputation: 64424

Add a <T> between static and 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);
    }
}

Upvotes: 2

Related Questions