Каст Object[] в CharSequnce[]

345
17 января 2017, 23:22

Доброго времени суток. Есть код ниже:

categories = pushPostPresenter.getCategories();
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        final CharSequence[] categoriesCharSequence = (CharSequence[]) categories.toArray();
        builder.setTitle(R.string.push_choose_category)
                .setItems(categoriesCharSequence, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        category = categoriesCharSequence[which].toString();
                    }
                });
        builder.create();

Суть в том, что метод .setItems() принимает на вход массив CharSequence[]. А переменная categories у меня типа ArrayList< String>. Собственно, мне пишет:

java.lang.ClassCastException: java.lang.Object[] cannot be cast to java.lang.CharSequence[]

Хотя, по-сути, toArray() возвращает массив объектов, почему мы не можем скастовать их в CharSequence[] ?

Как решить такую проблему? Спасибо.

Answer 1

Потому что Java не позволяет приводить Object[] к массиву более частного типа.

Воспользуйтесь методом toArray(T[] a) вместо toArray(), который вернёт массив нужного типа, как это сделано вот здесь

Answer 2

Ответ не столько на вопрос, сколько на разгоревшуюся дискуссию:

If T is an array type TC[], that is, an array of components of type TC, then a compile-time error occurs unless one of the following is true:

  • TC and SC are the same primitive type.

  • TC and SC are reference types and type SC can undergo casting conversion to TC.

http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.5.1

Дальше нужно проговорить одну особенность ArrayList. Дело в том, что не зная реального типа (см. type erasure), ArrayList хранит в себе данные в виде Object[]. С некоторыми ухищрениями он мог бы хранить и E[], но все равно до тех пор, пока он бы не был скомпилирован с реальным типом (насколько понимаю, вам бы в этом случае пришлось оперировать StringList extends ArrayList<String>, но могу ошибаться), E[] физически был бы Object[]. Массив, насколько мне известно, состоит из идентификатора типа, длины массива и непосредственно куском памяти для заполнения. В данном случае рантайм видит с левой и с правой стороны массивы, и получает их типы - CharSequence и Object, после чего убеждается, что Object не является CharSequence и выкидывает исключение - возвращай ArrayList<String> просто String[] под видом Object[], проблемы бы не существовало, но он, к сожалению, так не может, пока тип не прокидывается ему прямо в конструктор.

Метод с toArray(T[] targetTypeArray) абсолютно верный в плане разрешения этой проблемы.

Простите, если что напутал.

READ ALSO
Отладка тестов espresso

Отладка тестов espresso

Кто может подсказать как возможно отладить espresso тесты? К примеру на Calabash я просто запускал через эмулятор и прогонял по шаговоА тут в иерархией...

309
Почему не происходит подключения к MySql с помощью JDBC?

Почему не происходит подключения к MySql с помощью JDBC?

Всем доброго время сутокСкажите пожалуйста в чём может заключаться проблема при подключении к бд через JDBC? И возможно ли исправить? Пытался...

393
Как вызвать SharedPreferences в произвольном классе

Как вызвать SharedPreferences в произвольном классе

Есть виджет для АндроидаСуть его работы: парсить JSON с сайта и выводить некоторые данные

360
setAdapter долго загружает данные

setAdapter долго загружает данные

ЗдравствуйтеИмеется кастомный CursorAdapter

299