Перейти к содержимому

Java lang classcastexception что это

  • автор:

ошибка java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer

Задача простая. Чтобы один из элементов карточки заполнялся рандомным цветом и при клике на эту карточку открывалась активити, тулбар которой заполнялся бы тем же цветом. Но вылезает ошибка java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer Один тип не может быть приведен к другому. Меняла приведение типов, ничего не помогает. Ошибка именно при передачи цвета в тулбар, т.к. без этого код работает. Помогите разобраться. В onCreateViewHolder устанавливаю элементу рандомный цвет

 int[] androidColors = view.getResources().getIntArray(R.array.androidColors); int randomAndroidColor = androidColors[new Random().nextInt(androidColors.length)]; if (frameLayout != null)

В классе активити, показывающей подробное описание:

public static final String EXTRA_POEM_ID = "poem_id"; public static final String EXTRA_COLOR = "random_android_color"; private long poemId; private int randomAndroidColor; poemId = getIntent().getLongExtra(EXTRA_POEM_ID, -1); randomAndroidColor = getIntent().getIntExtra(EXTRA_COLOR, 0); toolbar.setBackgroundColor(randomAndroidColor); 

В адаптере создан интерфейс:

 itemView.setOnClickListener(new View.OnClickListener() < @Override public void onClick(View v) < long poemId = (Long) v.getTag(); int randomAndroidColor = (int) v.getTag(); onPoemClickListener.onPoemClick(poemId, randomAndroidColor); >>); > > public interface OnPoemClickListener

и код фрагмента, где располагается список с карточками

 private final PoemsAdapter.OnPoemClickListener onPoemClickListener = new PoemsAdapter.OnPoemClickListener() < @Override public void onPoemClick(long poemId, int randomAndroidColor) < Intent intent = new Intent(getActivity(), ReadActivity.class); intent.putExtra(ReadActivity.EXTRA_POEM_ID, poemId); intent.putExtra(ReadActivity.EXTRA_COLOR, randomAndroidColor); startActivity(intent); >>; 

6 Java исключений, которые преследуют новичков

Java-университет

6 Java исключений, которые преследуют новичков - 1

Время от времени я сталкиваюсь с разработчиками-новичками, которые застряли на понимании следующих простых исключений и мне приходиться все заново объяснять им. Скорей всего в подобной ситуации оказываются многие опытные Java разработчики, которые помогают новичкам справиться со следующими исключениями. Поэтому я решил написать эту статью и в будущем ссылаться на нее. Комментарии и добавления в список исключений приветствуются.

  1. NoClassDefFoundError : Это одно из тех исключений, которое сообщением Exception in thread “main“ NoClassDefFoundError часто приветствует новых разработчиков в мире Java программирования. Они пишут helloworld-программу, идут в командную строку и пишут “java“ — команду для выполнения и «БАМ»:-) Немного времени спустя новички поймут как исправить это исключение и увидят как выводиться их hello world. NoClassDefFoundError случается тогда, когда виртуальная машина Java (JVM) пытается получить доступ к классу во время исполнения и этот класс не находится, хотя тот же класс находился во время компиляции. Чаще всего это исключение случается при запуске Java программы через команду “java“ с неверным значением параметра classpath . [ Classpath – это параметр, который задается через командную строку или через переменную окружения, указывающий виртуальной Java машине или Java компилятору где искать классы или пакеты объявленные пользователем – прим. переводчика] Возможные причины исключения:
    • Класс недоступен в Classpath .
    • Часто скрипт, который исполняется при запуске операционной системы, изменяет значение переменной окружению classpath . Это можно проверить выполнив команду “ set ” в командной строке в Windows и посмотрев включено ли определение класса в значение classpath . При желании дальнейшее изучение этого исключения можно продолжить в блоге Javarevisited.
  2. ClassNotFoundException : Исключение ClassNotFoundException это еще одно исключение, из-за которого новичкам, только начинающим программировать на Java, снятся кошмары. Интересно что для среднего разработчика нужно некоторое время чтобы перестать путать ClassNotFoundException и NoClassDefFoundError между собой. И поэтому вопрос о разнице этих двух исключений остается одним из часто задаваемых на собеседовании на позицию junior Java разработчика.
    ClassNotFoundException случается когда JVM пытается загрузить определенный класс и не обнаруживает такого же в classpath . Обычно новички сталкиваются с этим в коде, который подключается к базе данных используя JDBC библиотеку. Пытаясь загрузить драйвер с помощью следующего кода Class.forName( “JDBCdriver”) . Хороший материал по ClassNotFoundException можно найти здесь. Так же рекомендуется ознакомиться и понять концепцию загрузчиков классов в Java чтобы эффективно справляться с этим исключением. Вы возможно захотите посмотреть следующую страницу о том как настроить classpath в окружениях Win/Unix. А так, как следует из документации Java, это исключение случается в следующих случаях:
    1. Когда пытаются загрузить класс используя метод Class.forName и файл .class не существует в classpath . Это самый частый случай из всех трех.
    2. Когда загрузчик класса пытается загрузить класс используя метод loadClass .
    3. Когда загрузчик класса пытается загрузить класс используя findSystemClass .
  3. NullPointerException : исключение NullPointerException понять легче и новички с ним справляются быстрее нежели с двумя предыдущими. В тоже время причину исключения очень легко найти так как приводится номер строки где оно случилось. В первую очередь исключение случается когда JVM пытается обратиться к null в том месте где должен был быть объект. Чаще всего это случается когда JVM пытается вызвать метод используя объект и оказывается что объект равен null . Другие случаи, как упоминается в документации Java, могут быть следующими:
    1. Получая доступ к или изменяя метод объекта, который равен null .
    2. Получая длину массива когда он равен null .
    3. Получая доступ к или меняя объекты, которые являются заключенными в массив, который равен null .

    Самый простой способ избежать этого исключения это добавить проверку на неравенство null (далее – проверка на null – прим. переводчика). Поэтому рано или поздно разработчик начинает это использовать и тогда проверки на null появляются везде. Интересно что использовать везде проверку на null не считается примером хорошего программирования. Основная причина почему проверка на null используется разработчиками это передавать объект null в случаи ошибки. В место этого пример хорошего программирования, который должен пропагандироваться программистами, это передавать пустой объект когда условие для главной/рабочей ветви программы не удовлетворяется. Это в свою очередь уменьшило бы количество проверок на null . Все-таки легче говорить нежели применять это на практике.:)

    Java lang classcastexception что это

    Брошенный, чтобы указать, что код попытался бросить объект к подклассу, которого это не экземпляр. Например, следующий код генерирует a ClassCastException :

    Object x = new Integer(0); System.out.println((String)x);

    Сводка конструктора

    Конструкции a ClassCastException без сообщения детали.

    Конструкции a ClassCastException с указанным сообщением детали.

    Сводка метода

    Методы java.lang унаследованный от класса. Throwable

    Методы java.lang унаследованный от класса. Объект

    Деталь конструктора

    ClassCastException
    public ClassCastException()

    Конструкции a ClassCastException без сообщения детали.

    ClassCastException

    Конструкции a ClassCastException с указанным сообщением детали.

    Платформа Java™
    Стандарт Эд. 7

    Представьте ошибку или функцию
    Для дальнейшей ссылки API и документации разработчика, см. Java Документация SE . Та документация содержит более подробные, предназначенные разработчиком описания, с концептуальными краткими обзорами, определениями сроков, обходных решений, и рабочих примеров кода.
    Авторское право © 1993, 2011, Oracle и/или его филиалы. Все права защищены.

    3 трюка для устранения странных ошибок с дженериками

    Деловое фото создано yanalya — www.freepik.com

    Большинство разработчиков Java используют дженерики без глубоких знаний. А вы должны знать ответы на эти вопросы. Если вы будете знать их, вы устраните многие проблемы, связанные с generics .

    Давайте ответим на эти вопросы.

    1. Вы можете использовать extends с интерфейсами

    Согласно этим документам, вы можете использовать interfaceType после ключевого слова extends . Вы можете соединить их в цепочку, чтобы сформировать типы пересечения. Это может привести к странным ошибкам во время выполнения.

    Давайте рассмотрим следующий вопрос на Stack Overflow.

    Код в вопросе следующий:

     X getCharSequence() < return (X) "hello"; > X getString()

    Если мы запустим его в jShell 11, то получим следующий результат:

    jshell> X getCharSequence() < . >return (X) "hello"; . > > . > . > X getString() < . >return (X) "hello"; . > > | Warning: | unchecked cast | required: X | found: java.lang.String | return (X) "hello"; | ^-----^ | created method getCharSequence() | Warning: | unchecked cast | required: X | found: java.lang.String | return (X) "hello"; | ^-----^ | created method getString() jshell> Integer x = getCharSequence(); . > | Exception java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap') | at (#3:1) jshell> Integer y = getString(); . > | Error: | incompatible types: inference variable X has incompatible upper bounds java.lang.Integer,java.lang.String | Integer y = getString();

    В обоих примерах мы получаем предупреждение о непроверенном приведении. Это потому, что в обоих примерах мы возвращаем String , а не X . Тем не менее, оба метода создаются.

    Когда мы загружаем getCharSequence , мы получаем не ошибку времени компиляции, а ошибку времени выполнения. Для getString мы получаем ошибку времени компиляции.

    Почему так происходит?

    Для первого метода Java определяет тип пересечения. В данном случае это Integer & CharSequence а Integer может быть подклассом CharSequence . Вот почему с точки зрения компиляции это корректное присваивание, несмотря на то, что Integer является final class.

    Ошибка во время выполнения возникает, поскольку мы возвращаем значение String , не соответствующее типу Integer & CharSequence . Поскольку проверки во время выполнения нет, мы получаем исключение ClassCastException .

    Почему во втором примере возникает ошибка времени компиляции?

    String — это final класс, и вы не можете расширить его как String . Он не относится к типу CharSequence , который является интерфейсом. Ему невозможно иметь тип пересечения Integer & String , и это известно во время компиляции.

    2. Вы можете создавать типобезопасные generic массивы

    Один из способов создания generic массивов заключается в следующем:

    public T[] array(T. values)

    Но даже в этом случае выдается следующее предупреждение:

    jshell> public T[] array(T. values) < . >return values; . > > | Warning: | Possible heap pollution from parameterized vararg type T | public T[] array(T. values) < | ^---------^ | created method array(T. )

    Так что же означает загрязнение кучи (heap pollution)?

    Переменная содержит ссылку на неправильный тип. Или, другими словами, тип переменной не является нужным типом.

    Heap pollution (загрязнение кучи) происходит, когда переменная параметризованного типа ссылается на объект, не относящийся к этому параметризованному типу. Такая ситуация возникает, если программа выполнила какую-то операцию, которая вызывает непроверенное предупреждение во время компиляции. Непроверенное предупреждение выдается, если либо во время компиляции (в рамках правил проверки типов во время компиляции), либо во время выполнения невозможно проверить корректность операции с параметризованным типом (например, приведение или вызов метода). Например, загрязнение кучи происходит при смешивании необработанных и параметризованных типов или при выполнении непроверенных приведений типов source

    Вы можете подавить эти предупреждения. И это используется в одном методе, который мы все используем: Collections#emptyList()

    Так почему же этот сценарий хорош?

    Вы можете быть уверены, что даже при стирании типов (type erasure) будет создан пустой список нужного типа. Вы можете быть спокойны, потому что это пустой список, поэтому подойдет любой тип.

    Таким образом, проблема заключается в безопасности типов, и для ее решения вам необходимо предоставить нужный тип. Вы можете сделать это с помощью функции генератора. Она используется в функции toArray .

    А вот наша собственная реализация.

    jshell> class Generic  < . >. > private E[] array; . > . > GenericSet(IntFunction generator) < . >this.array = generator.apply(0); . > > . > . > public static void main(String[] args) < . >Generic ofString = . > new Generic<>(String[]::new); . > Generic ofDouble = . > new Generic<>(Double[]::new); . > > . > >

    3. Producer Extends, Consumer Super

    Я полагаю, вы встречали и extends и super в Java коде с generic.

    Так почему вы должны использовать extends ? Каковы ограничения extends ? И какова цель super ?

    • Producer Extends — если вам нужен List , чтобы выдавать значения T (вы хотите читать T из списка), вам нужно объявить его с помощью ? extends T , например, List . Но вы не можете добавить значение в этот список.
    • Consumer Super— если вам нужен List для получения значений типа T (вы хотите записывать значения типа T в список), вам нужно объявить его с помощью ? super T , например, List . Но нет никаких гарантий, какой тип объекта вы можете прочитать из этого списка.

    Вы не можете добавить в список производителей, и вы не можете прочитать из списка потребителей.

    jshell> List foo3 = List.of(1.23); foo3 ==> [1.23] jshell> foo3.get(0) $27 ==> 1.23 jshell> foo3.add(1.34) | Error: | incompatible types: double cannot be converted to capture#10 of ? extends java.lang.Number | foo3.add(1.34) | ^--^
    jshell> List foo3 = new ArrayList(); foo3 ==> [] jshell> foo3.add(1) $32 ==> true jshell> foo3 foo3 ==> [1] jshell> foo3.get(0) $34 ==> 1 jshell> Number r = foo3.get(0) | Error: | incompatible types: capture#11 of ? super java.lang.Number cannot be converted to java.lang.Number | Number r = foo3.get(0); | ^---------^

    Почему это происходит?

    Нет гарантии с обеих сторон, так как происходит стирание типов.

    Когда вы используете extends , у вас есть гарантия того, что вы можете читать. Это тип после wildcard знака extends или его подклассов. И у вас нет гарантии того, что вы можете добавить, так как тип стирается во время выполнения.

    Когда вы используете super , у вас есть гарантия того, какой тип вы можете добавить. Это тип после wildcard super или его подклассов. И у вас нет гарантии того, что вы можете прочитать, так как тип стирается во время выполнения.

    Еще одно хорошее и простое объяснение (source):

    dst будет потреблять значения типа T, поэтому wildcard super гарантирует это. src будет производить значения, поэтому extends будет гарантировать это. Но даже в этом случае нет гарантии типа при добавлении в src или чтении из dst .

    Что, если вы заранее знаете типы и хотите использовать wildcard?

    Вы можете немного обмануть компилятор. Кроме того, вы получите предупреждение, которое можно подавить с помощью аннотации компилятора. Но поскольку вы уверены в типах, которые вы предоставляете, это будет работать для вашего сценария.

    Допустим, мы используем super (Consumer из PECS) для foo3 . С помощью явного приведения к List вы можете гарантировать какой тип вы читаете из foo3Unchecked . В данном случае мы гарантируем, что это Number что чтение Integer приведет к ошибке преобразования.

    Какие особенности дженериков вы знаете? Дайте мне знать в разделе комментариев.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *