Тип безопасности: снятый флажок из объекта в список <MyObject> - программирование
Подтвердить что ты не робот

Тип безопасности: снятый флажок из объекта в список <MyObject>

У меня есть ListView, в котором перечисляется пользовательский объект (скажем MyObject).

Я хочу динамически отфильтровывать его с помощью EditText, поэтому мне пришлось реализовать getFilter() с методом publishResults:

@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
    MyObjectAdapter.this.setItems((List<MyObject>) results.values);
    MyObjectAdapter.this.notifyDataSetChanged();
}

В этот момент Eclipse жалуется: Type safety: Unchecked cast from Object to List<MyObject>

Я уверен, что этот приведение всегда будет истинным, но Eclipse предлагает только добавить @SuppressWarnings("unchecked"), но я полностью против SuppressWarnings, потому что он только скрывает проблему, а не решение...

Я попробовал добавить:

if(results.values instanceof List<MyObject>)

Но Eclipse снова жалуется, и это ничего не решает...

Cannot perform instanceof check against parameterized type List<MyObject>. Use the form List<?>

Я знаю, что кастинг всегда будет правильным, но который является правильным способом убедиться, что код results.values на самом деле является List<MyObject>?

Спасибо заранее!

4b9b3361

Ответ 1

Ну, наконец, мне удалось найти решение.

Так же, как @Medo42 сказал:

Другой вариант - проверить и перечислить в List как instanceof ошибка. Затем вы можете перебирать элементы в списке и проверьте, действительно ли они все экземпляры MyObject, и скопируйте их в новый список.

Несмотря на то, что я не прошел процесс создания целого нового объекта, чтобы этот конкретный случай работал "без предупреждения", это было правильное направление.

Итак, я взял идею @lokoko и использовал ее в новом setItems() методе с параметром Object вместо List<MyObject>, чтобы убедиться, что

Код результата следующий:

public void setItems(List<MyObject> var){
    this.list = var;
}

public void setItems(Object var){
    List<MyObject> result = new ArrayList<MyObject>();
    if (var instanceof List){
        for(int i = 0; i < ((List<?>)var).size(); i++){
            Object item = ((List<?>) var).get(i);
            if(item instanceof MyObject){
                result.add((MyObject) item);
            }
        }
    }
    setItems(result);
}

Спасибо всем за вашу помощь!

Ответ 2

Если все, с чем вам нужно работать, это Object, то вы не можете проверить во время выполнения, что у вас действительно есть List<MyObject>, потому что общий тип MyObject используется только для проверки типа компиляции, он недоступен во время выполнения. Вот почему вы получаете сообщение об ошибке при попытке добавить проверку instanceof.

Если вы уверены, что ваш Object действительно всегда List<MyObject>, тогда я бы сказал, что @SuppressWarnings в порядке, если вы документируете, почему вы уверены, что это не проблема.

Если вы абсолютно хотите избежать предупреждения, вы можете создать свою собственную реализацию List (скажем, MyObjectList), которая сама по себе не является общей, но реализует List<MyObject>. Затем вы можете выполнить проверку instanceof против MyObjectList во время выполнения.

Другая опция - проверить и приложить к List<?>, как указывает ошибка instanceof. Затем вы можете перебирать элементы в списке и проверять, действительно ли они все экземпляры MyObject, и скопировать их в новый List<MyObject>.

Ответ 3

Попробуйте что-то вроде этого:

List<?> result = (List<?>) results.values;
for (Object object : result) {
    if (object instanceof MyObject) {
        tempList.add((MyObject) object); // <-- add to temp
    }
}

filteredItems = tempList; // <-- set filtered

Ответ 4

Вы можете выполнить проверку перед тем, как передать ее в setItems().

final Object myListObj = reuslts.values;
if(myListObj instanceof List<?>) {
    if(((List<?>)myListObj).get(0) instanceof MyObject)
        // You can safely suppress the warning here because you made sure it is a List containing MyObject
        MyObjectAdapter.this.setItems((List<? extends MyObject>) myListObj);

}

Однако вам необходимо соответствующим образом изменить ваш метод setItems():

public void setItems(List<? extends MyObject> list) {
    // Your code here
}