2017-02-03 1 views
2

У меня есть следующее объявление класса:Java Ошибка пропускание аргумента в метод, который принимает T, где T расширяет Сопоставимый <T>

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

    } 
} 

Если бы я сделал это правильно, что я хотел это: UserVariable можно сравнить с другими UserVariable s и является общим и принимает тип T, который можно сравнить с другим T s.

У меня возникли проблемы вызывающую setValue() и передавая ей Integer:

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

дает мне ошибку «Метод setValue(Comparable<Comparable<T>>) в типе UserVariable<Comparable<Comparable<T>>> не применяется для аргументов (Integer)».

Я не понимаю, почему я получаю эту ошибку. Во-первых, Integer действительно реализует Comparable<Integer>. Во-вторых, почему Comparable появляются дважды, вложенным способом (Comparable<Comparable<T>>) в сообщение об ошибке? Да, UserVariable также реализует Comparable, но ошибка относится к типу параметра метода, который имеет тип T, который должен быть просто T extends Comparable<T>, правильно?

UPDATE:

Я понял, что проблема связана с тем, что я извлечения объекта из подстановочных коллекции:

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

Добавление выше код будет воспроизвести ошибку компиляции на Последняя линия.

Мои извинения, я боюсь, что область вопроса полностью изменилась с последней информацией, потому что я вытаскиваю объект с карты типа UserVariable<?> и пытаюсь позвонить setValue().

+3

Вы должны использовать '>', однако, видя что 'Integer' implments' Comparable ', а не' Comparable 'это вряд ли является источником вашей проблемы. – kajacx

+1

'public setValue' должен быть' public void setValue'. в противном случае, после реализации compareTo, я могу вызвать 'setValue (новый Integer (20))' без ошибки –

+0

возможных дубликатов: http://stackoverflow.com/questions/5013947/create-a-compareto-to-a-generic- class-that-implementables-compar, http://stackoverflow.com/questions/21544716/implementing-comparable-with-a-generic-class – cuddlecheek

ответ

1

Есть две вещи, которые нуждаются в изменении:

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

    В объявлении класса, вы реализуете Comparable<UserVariable<T>> где UserVariable сам снова реализует Comparable, поэтому вы получаете Comparable<Comparable<T>> в сообщении об ошибке.

  • public setValue(T value)

    Не знаю, является ли это опечатка, но метод требует типа возвращаемого, вы можете изменить его на public void setValue(T value)

Ниже приведен пример, который работает после внесения этих изменений:

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

Если вы хотите сравнить два UserVariable объекты, с которыми вам просто нужно реализовать compareTo метод и добавить return type к присваивателя, ниже должно работать:

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

Спасибо. Тем не менее, я хотел бы иметь возможность сравнивать 'UserVariable ' с другим 'UserVariable ', вместо того, чтобы сравнивать его с 'T' – skrilmps

+0

@skrilmps. Я обновил свой ответ и добавил еще один пример для' UserVariable '. –