Class java lang integer cannot be cast to class java lang string

How to fix java.lang.classcastexception cannot be cast to in Java — cause and solution

As name suggests ClassCastException in Java comes when we try to type cast an object and object is not of the type we are trying to cast into. In fact ClassCastException in Java is one of most common exception in Java along with java.lang.OutOfMemoryError and ClassNotFoundException in Java before Generics was introduced in Java 5 to avoid frequent instances of java.lang.classcastexception cannot be cast to while working with Collection classes like ArrayList and HashMap, which were not type-safe before Java 5. Though we can minimize and avoid java.lang.ClassCastException in Java by using Generics and writing type-safe parameterized classes and method, its good to know real cause of ClassCastException and How to solve it.

In this Java tutorial we will see Why java.lang.ClassCastException comes and how to resolve ClassCastException in Java. We will also see how to minimize or avoid ClassCastException in Java by using Generics, as prevention is always better than cure.

Cause of java.lang.ClassCastException in Java

How to fix java.lang.ClassCastException in Java cause and solution

In order to understand cause of ClassCastException , you need to be familiar with concept of type casting in Java. Since Java is an object oriented programming language and supports features like Inheritance and Polymorphism, a reference variable of type parent class can represent object of child class. This leads to ClassCastException if object is not of type on which you are casting it. It can be best explained with an example. Let’s see a sample code which will throw ClassCastException in Java:

Читайте также:  Javascript document all classname

Exception in thread «main» java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer

If you see closely we were trying to cast an String object into an Integer object which is not correct and that’s why Java throws java.lang.classcastexception cannot be cast to error . Problems can become more difficult if all class are closely related.

Since due to polymorphism in Java an Object instance can hold any type of Object but you can only cast between same type. what makes this problem worse is that it only comes during runtime, ClassCastException doesn’t come at compile time which makes it hard to detect specially in large enterprise Java application or high frequency electronic trading system where input comes from upstream and in production various kinds of input are available.

This was frequent problem with Java Collection classes like LinkedList and HashSet in Java which holds Object type but with introduction of Generics in Java 5 solved this problem by checking type-safety during compile time. Which means you can not store Integers on LinkedList of String, from Java 5 it will result in compile time error.

Common source of java.lang.ClassCastException

1. Java Collection classes like HashMap , ArrayList , Vector or Hashtable which is not using Generics.

2. Methods which were written to take advantage of polymorphic behavior and coded on interfaces prior to Java 5 and doesn’t used parameter to provide type-safety. look for all places where you have used cast operator in Java and verify that whether that code is type-safe or not.

Here are some of the most frequently occurred ClassCastException in Java:

java.lang.classcastexception java.lang.string cannot be cast to java.lang.integer

This will come when you try to cast String object to Integer i.e.
Integer number = (Integer) stringObject;

java.lang.classcastexception java.lang.string cannot be cast to java.util.date :
This error will come when you cast String to Date in Java, since both are not related to each other, it will not possible to typecast them.

java.lang.classcastexception java.util.arraylist cannot be cast to java.lang.string
I have seen this happening a lot in beginners code based on Java Collection framework, Since ArrayList and String are not related to each other, following casting will throw this error :

String str = (String) arrayListObject;

But if you definitely wants to convert ArrayList to String, than check this post about converting collection to String in Java.

Here are couple of more examples, which is self explanatory.

java.lang.classcastexception java.util.arraylist cannot be cast to java.util.map
java.lang.classcastexception ljava.lang.object cannot be cast to ljava.lang.comparable
java.lang.classcastexception ljava.lang.object cannot be cast to ljava.lang.integer
java.lang.classcastexception ljava.lang.object cannot be cast to java.util.list
java.util.arraylist cannot be cast to java.lang.comparable

How to fix java.lang.ClassCastException in Java

Solving ClassCastException can be very easy once you understand polymorphism in Java and difference between compile time and runtime things. ClassCastException are simple like NullPointerException just look the stack-trace and go to the line number. Many of advanced Java IDE like Eclipse and Netbeans will give you hyperlink to navigate till culprit line number in Java file.

Now you know where exactly ClassCastException is coming and stack trace also told which object it was trying to cast, Now you have to find, how that type of object comes and this could take some time based upon complexity of your java application. You can also prevent ClassCastException in Java by using Generics.

Generics are designed to write type-safe code and provides compile-time checks which tends to violate type-safety. By using Generics in Collection classes and other places you can safely minimize java.lang.ClassCastException in Java.

That’s all on What is ClassCastException in Java and how to solve Exception in thread «main» java.lang.ClassCastException. I highly recommend to use Generics while using any Collection classes or class which acts as container e.g. ThreadLocal in Java. Also write your own classes and method to take advantage of Generics to provide type-safety as shown in this example of How to write parameterized class. It’s also a good idea to refresh your knowledge on type-casting in Java.

Источник

Русские Блоги

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

public static void main(String[] args) < Maptt= new HashMap(); int a = 187117; tt.put("aa",a); try < long b = (long) tt.get("aa"); // long b = Long.valueOf(String.valueOf(tt.get("aa"))).longValue(); System.out.println(b); >catch (Exception e ) < e.printStackTrace(); >>

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
at com.facishare.appserver.test.MyTest.main(MyTest.java:878)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

Но если мы поместим длинный тип непосредственно при вставке карты, ошибки не будет. Если пользователь не уверен, какой тип int передается, произойдет ошибка преобразования.

Конкретное объяснение таково:

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

Когда параметром интерфейса является Map , когда значение KEY извлекается, оно принудительно преобразовывается в String, возникает указанное выше исключение
Анализ проблемы

Причина использования Map в качестве параметра: можно передать несколько параметров; если в качестве параметра используется класс PO, необходимо обновить версию, если на нее ссылаются в разных проектах;
Причина проблемы: интерфейс предоставляется извне, и нет четкого комментария к интерфейсу. Каково значение ключа. Только тот, кто написал этот интерфейс в то время, мог бы избежать этой проблемы. Другие вызывающие абоненты Непонятно, результат принудительно конвертировать после вызова интерфейса
Анализ на уровне кода: корень проблемы в различии между универсальными шаблонами и Object

// Пример: имитировать сохранение целого числа на карте и принудительно преобразовать его в строку после извлечения public static void main(String[] args) < Mapparams = new HashMap(); // значение имеет тип int params.put("1", 1); // Вывести значение в String // Появляется здесь во время выполнения // java.lang.Integer cannot be cast to java.lang.String String result = (String)params.get("1"); System.out.println(result); > 

проблема:

  • Тип возвращаемого значения map.get («») — Object. Почему возникает исключение при преобразовании Object в String?
// исходный код java -version 1.7.0_79 // 1. Структура данных java.util.Map // HashMap использует метод адресации цепочки для разрешения конфликтов хешей: // Все представляет собой структуру массива, каждая позиция в массиве хранит связанный список, а Entry - это узел в связанном списке transient Entry[] table = (Entry[]) EMPTY_TABLE; // Получено из Entry , где K, V являются общими // 2. помещаем метод в java.util.HashMap public V put(K key, V value) < >// Типы параметров в методе все общие, соответствующие Entry // 3. Преимущества дженериков // Тип данных может быть подтвержден во время компиляции // 4. Разница между generic и Object // Использование общих значений без преобразования типа; объект требует преобразования // Используя обобщения в качестве параметров, несогласованные типы данных могут быть обнаружены во время компиляции // Такие как: Map params = new HashMap(); params.put("1",1); params.put (2,2); // Во время компиляции появляется запрос об исключении; K k, укажите тип данных универсального типа K как String // 5. JVM стирает универсальный тип в компиляторе в соответствии с выполненным универсальным типом данных // В JVM нет концепции дженериков // JVM компилируется в соответствии с указанным типом данных, как в приведенном выше примере, VALUE - это тип int // После того, как JVM скомпилирует код, VALUE станет типом int // 6. Анализируем результаты в приведенном выше примере Object object = params.get("1"); if(object instanceof Integer) < System.out.println ("true"); // Консоль выводит true // Это видно из выходного результата: хотя результат, взятый с карты, - это объект, его суть - целое число, поэтому, когда он принудительно устанавливается на String, возникает исключение преобразования типа >
// Пример: решение String result1 = String.valueOf(object); // String.valueOf по существу вызывает метод object.toString () System.out.println(result1); 

краткое изложение проблемы

Когда Map используется в качестве типа параметра интерфейса, необходимо указать тип данных KEY и соответствующее VALUE
При получении значений из параметров Map обратите внимание на возможность исключений преобразования. Чтобы избежать вышеуказанных проблем, вы можете судить по instanceOf; вы можете использовать toString () / String.valueOf ( ) Сначала преобразуйте его в String, а затем в требуемый тип данных
Общий

Общие выражения и значения дженериков

E-Element (используется в коллекции, потому что коллекция является элементом)
T — Тип (класс Java)
K — ключ
V — Значение
N — Число (тип числа)
? — Представляет неопределенный тип Java (неограниченный тип подстановки)
S、U、V – 2nd、3rd、4th types

Источник

Возможно тупой вопрос по обобщениям в Java

Почему это работает? Почему он может скастовать Object до дочерних классов внутри обобщенных классов? хотя при явном указании типов как здесь:

 String[] str = (String[]) new Object[10]; 

возникает Exception in thread «main» java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;

Потому что массив объектов не может быть приведен к массиву строк

согласен, но если выполнить

MyTestClass myTestClass = new MyTestClass(); myTestClass.set("MyText"); System.out.println(myTestClass.get(0)); 

то происходит приведение массива объектов к массиву строк, разве нет?

Подозреваю, что Object[] целиком никогда и не приводится к T[] (в твоем случае — Integer[]), потому и не падает. В рантайме он всегда остается Object[].

А вот отдельный элемент, Object[0] (Object) легко превращается в Integer[0] (Integer).

И вообще, массивы — сакс. Пользуйся ArrayList, как белый человек.

Грубо говоря, Object[] не является базовым классом для String[], при этом класс String наследник класса Object, приведение легально.

про ArrayList знаю, но хочется понять принцип функционирования сабжа

Нет, происходит приведение конкретных элементов массива.

где можно об этом почитать? Что-то никак вникнуть не могу

UPDATE: разобрался, спасибо за помощь

r0ck3r ★★★★★ ( 01.08.16 23:26:15 MSK )
Последнее исправление: r0ck3r 01.08.16 23:30:25 MSK (всего исправлений: 1)

— Не пытайся понять то, чего понять не можешь.

Такие вопросы больше для самоутверждения на собеседованиях. В жизни оно не пригодится.

public class Main < public static class MyTestClass < private T[] myAr; private int curItem=0; private int count=10; MyTestClass()< myAr = (T[]) new Object[count]; //Этот код работает for(int i=0; i> void set(T value) < if(curItem> T get(int index) < System.out.println("Class from the inside " + myAr.getClass()); return myAr[index]; >> public static void main(String[] args) < MyTestClassmyTestClass = new MyTestClass(); myTestClass.set(12); System.out.println(myTestClass.get(0)); // Напечатает Class from the inside System.out.println("Class from the outside " + myTestClass.myAr.getClass()); // Упадем уже здесь String[] str = (String[]) new Object[10]; //Этот код не работает, хотя, как мне кажется, делает тоже самое > > 

Единственное, что нужно знать — массивы очень не ОК для дженериков, коллекции гораздо лучше.

Повнимательней пройдись по каждой строчке в твоём коде. Убери дженерики, понятнее будет. Возможно ты упускаешь, что никаких дженериков в рантйме нет.

MyTestClass myTestClass = new MyTestClass();

Создаём объект класса MyTestClass. Так как jvm ничего не знает про дженерики, то внутри myAr есть массив Object[].

В массив myArr кладётся строка «MyText». Так как в рантайме никаких дженериков нет, то при передаче аргумента в функцию String приводится в Object и в массив кладётся обычный Object.

System.out.println(myTestClass.get(0));

Тоже самое. Функция get() возвращает Object, внутри класса MyTestClass никаких приведений не происходит. Приведение типа выполняется во время передачи аргумента в System.out.println.

Источник

Оцените статью