The ClassCastException is thrown when you try to cast an object to a class it is not an instance of. Java allows you to cast objects in the type hierarchy, but if the actual runtime type doesn't match the target type, this exception is thrown.
Object obj = "Hello";
// ❌ Problem
Integer num = (Integer) obj; // ClassCastException!
// ✅ Solution 1: Check with instanceof first
if (obj instanceof Integer) {
Integer num = (Integer) obj;
}
// ✅ Solution 2: Pattern matching (Java 16+)
if (obj instanceof Integer num) {
System.out.println(num + 1); // num is already cast
}
Animal animal = new Dog();
Cat cat = (Cat) animal; // ❌ Dog cannot be cast to Cat!
Animal animal = new Dog();
// ✅ Check before casting
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark();
} else if (animal instanceof Cat) {
Cat cat = (Cat) animal;
cat.meow();
}
// ✅ Java 16+ pattern matching
if (animal instanceof Dog dog) {
dog.bark(); // dog is already typed as Dog
}
// ❌ Raw type "” no type safety
List list = new ArrayList();
list.add("Hello");
list.add(42);
Integer num = (Integer) list.get(0); // ClassCastException! It's a String!
// ✅ Use generics for type safety
List<String> strings = new ArrayList<>();
strings.add("Hello");
// strings.add(42); // Compile error "” caught early!
String s = strings.get(0); // No cast needed!
Map<String, Object> data = new HashMap<>();
data.put("age", "25"); // Stored as String
Integer age = (Integer) data.get("age"); // ClassCastException!
Map<String, Object> data = new HashMap<>();
data.put("age", "25");
// ✅ Check type before casting
Object ageObj = data.get("age");
if (ageObj instanceof Integer) {
Integer age = (Integer) ageObj;
} else if (ageObj instanceof String) {
Integer age = Integer.parseInt((String) ageObj);
}
// ✅ Or use a typed helper
@SuppressWarnings("unchecked")
public static <T> T getAs(Map<String, Object> map, String key, Class<T> type) {
Object value = map.get(key);
if (type.isInstance(value)) return type.cast(value);
throw new ClassCastException("Expected " + type + " but got " + value.getClass());
}
// ✅ Safe polymorphic dispatch
List<Shape> shapes = Arrays.asList(new Circle(5), new Rectangle(3, 4));
for (Shape shape : shapes) {
if (shape instanceof Circle c) {
System.out.println("Circle area: " + Math.PI * c.getRadius() * c.getRadius());
} else if (shape instanceof Rectangle r) {
System.out.println("Rectangle area: " + r.getWidth() * r.getHeight());
}
}
It's thrown when you try to cast an object to a type it's not an instance of. For example, casting a String to Integer, or a Dog to Cat when they don't share a common hierarchy.
Use instanceof before casting: if (obj instanceof Dog) { Dog d = (Dog) obj; }. In Java 16+, use pattern matching: if (obj instanceof Dog d) { d.bark(); }
Generics enforce type constraints at compile time. List<String> only accepts Strings, so you never need to cast when retrieving elements, and the compiler catches type mismatches early.
It combines the instanceof check and cast: if (obj instanceof String s) { ... }. The variable s is automatically typed as String within the if block, eliminating the explicit cast.
Yes, it's a RuntimeException. But catching it is usually a sign of poor design. Better to use instanceof checks or generics to prevent it from occurring in the first place.
Explore 500+ free tutorials across 20+ languages and frameworks.