skrilmps
skrilmps

Reputation: 695

Java Error passing an argument to a method that takes T where T extends Comparable<T>

I have the following class declaration:

public class UserVariable<T extends Comparable<T>> implements Comparable<UserVariable<T>>
{
    private T myValue;

    public void setValue(T value)
    {
        myValue = value;
    }

    public T getValue()
    {
        return myValue;
    }

    public int compareTo(UserVariable<T> rhs)
    {
        return getValue().compareTo(rhs.getValue());

    }
}

If I did that correctly, what I wanted is: UserVariable can be compared to other UserVariables and it's generic and accepts a type T that can be compared to other Ts.

I am having trouble invoking setValue() and passing it an Integer:

UserVariable<Integer> newVar = new UserVariable<Integer>();
newVar.setValue(new Integer(20));

gives me the error "The method setValue(Comparable<Comparable<T>>) in the type UserVariable<Comparable<Comparable<T>>> is not applicable for the arguments (Integer)".

I don't understand why I'm getting this error. First, Integer does implement Comparable<Integer>. Second, why does Comparable appear twice, in a nested fashion (Comparable<Comparable<T>>) in the error message? Yes, UserVariable also implements Comparable but the error is referring to the type of the method parameter, which is of type T, which should just be a T extends Comparable<T>, right?

UPDATE:

I've realized the problem is connected with the fact that I am retrieving the object from a wildcard collection:

Map<String, UserVariable<?>> myVars = new HashMap<>();

UserVariable<Double> v1 = new UserVariable<>();
v1.setValue(3.0);

myVars.put("doubleVar", v1);

myVars.get("doubleVar").setValue(new Double(30));

Adding the above code will reproduce the compile error on the last line.

My apologies, I'm afraid the question scope has changed entirely with that latest info, because I am pulling an object from the map of type UserVariable<?> and trying to call setValue() on that.

Upvotes: 2

Views: 1690

Answers (1)

Darshan Mehta
Darshan Mehta

Reputation: 30809

There are two things that need changing:

  • public class UserVariable<T extends Comparable<T>> implements Comparable<UserVariable<T>>

    In class declaration, you are implementing Comparable<UserVariable<T>> where UserVariable itself again implements Comparable that's why you are getting Comparable<Comparable<T>> in the error message.

  • public setValue(T value)

    Don't know whether it's a typo but the method needs a return type, you can change it to public void setValue(T value)

Below is an example that works after making these changes:

public class UserVariable<T extends Comparable<T>> implements Comparable<T> {

    @Override
    public int compareTo(T o) {
        // TODO Auto-generated method stub
        return 0;
    }

    private T myValue;

    public void setValue(T value){
        myValue = value;
    }

    public static void main(String[] args) {
        UserVariable<Integer> newVar = new UserVariable<Integer>();
        newVar.setValue(new Integer(20));
    }
}

Update

If you want to compare two UserVariable objects the you just need to implement compareTo method and add return type to setter method, below should work:

public class UserVariable<T extends Comparable<T>> implements Comparable<UserVariable<T>> {
    private T myValue;

    public void setValue(T value) {
        myValue = value;
    }

    public T getValue() {
        return myValue;
    }

    public int compareTo(UserVariable<T> rhs) {
        return getValue().compareTo(rhs.getValue());

    }

    public static void main(String[] args) {
        UserVariable<Integer> newVar = new UserVariable<Integer>();
        newVar.setValue(new Integer(20));
    }
}

Upvotes: 1

Related Questions