Java - Generics - Преобразование универсального объекта в указанный объект не работает - PullRequest
0 голосов
/ 23 ноября 2018

Я пытаюсь решить эту, по-видимому, простую универсальную проблему приведения:

Во-первых, объявляю этот простой универсальный объект:

public interface GenericObject<T> {}

Во-вторых, объявляю этот рабочий интерфейс:

public interface Generic { // I don't want to do Generic<T>

    <T> void setGenericObject(GenericObject<T> obj);

}

Тогда давайте реализуем этот интерфейс:

public class GenericImpl implements Generic {

    private GenericObject<String> genericObject; // This is needed

    @Override
    public <String> void setGenericObject(GenericObject<String> obj) {
        genericObject = obj; // eclipse give me this error :
                             // Type mismatch: cannot convert from 
                             // interfaces.GenericObject<String> to
                             // interfaces.GenericObject<java.lang.String>
    }

}

Как я могу решить эту ошибку?

Редактировать:

На самом деле, единственный способ, которым я долженрешить эту проблему, чтобы сделать это:

public class GenericImpl implements Generic {

    private GenericObject<String> genericObject; 

    @SuppressWarnings("unchecked") // I don't realy like this
    @Override
    public <T> void setGenericObject(GenericObject<T> obj) {
        genericObject = (GenericObject<String>) obj;
    }

}

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Случай 1:

Если T не используется в Generic, просто используйте подстановочный знак.

class Generic {
    List<?> list;
    void set(List<?> list) {
        this.list = list;
    }
    int size() {
        return list.size(); // doesn't care about T
    }
}

Случай 2:

Если T используется только в качестве локальных переменных , тогда объявите <T> для метода

class Generic {
    <T> void swapFirstAndSecond(List<T> list) {
        T first = list.get(0), second = list.get(1);
        list.set(1, first);
        list.set(0, second);
    }
}

Случай 3:

Если несколько поля и методы используют один и тот же тип T, но точный тип T не важен, тогда делакре <T> для класса

class Generic<T> {
    List<T> list;
    void set(List<T> list) {
        this.list = list;
    }
    T getFirst() {
        return list.get(0);
    }
}

Случай 4:

Если T должен быть определенного типа, например String, то не объявляйте параметр типа <T>

class Generic {
    List<String> list;
    void set(List<String> list) {
        this.list = list;
    }
    boolean isFirstContainsSecond() {
        String first = list.get(0), second = list.get(1);
        // call String.contains here, so T must be String
        return first.contains(second);
    }
}
0 голосов
/ 23 ноября 2018

Реальная проблема заключается в том, что

public <String> void setGenericObject(GenericObject<String> obj)

, где String не имеет ничего общего с вашим предполагаемым java.lang.String.Здесь String - это просто параметр типа, имя которого String случайно.

Пожалуйста, обратитесь к Возможно ли определить интерфейсный метод с помощью универсального возвращаемого типа и конкретную реализацию, определяющуютип возврата? .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...