4

Hi Check the below code

   ArrayList x=new ArrayList();
   ArrayList<String>y=x;
   ArrayList<StringBuffer>z=x;
   y.add("Strings");
   System.out.println(z.get(0).toString());

Am getting Class Cast Exception at System.out.println

 java.lang.ClassCastException: java.lang.String
 at com.one.MainClass.main(MainClass.java:16)

But when i am trying

  System.out.println(z.get(0)) 

it is working why this coming ??

Anand K Nair
  • 597
  • 1
  • 6
  • 18

2 Answers2

2

I assume that you are doing that as an experiment (if not then read the other answers as to how you should have written your code).

x is a raw ArrayList, in which you can place any types of objects.

y.add("string") adds a String.

z is an ArrayList<StringBuffer> and expects StringBuffers. When you call z.get(0), the JVM tries to cast the element at index 0 to a StringBuffer before returning it. That cast fails.

In other words, although StringBuffer s = z.get(0); compiles, it will throw a ClassCastException at runtime because z.get(0) is not a StringBuffer.

assylias
  • 321,522
  • 82
  • 660
  • 783
1

The specifics as to why you are getting your problem is this:

  • New ArrayList is created, empty
  • All elements are typed to String in y
  • All elements are typed to StringBuffer in z
  • A new element is added to this array list.
  • The JVM attempts to cast it to BOTH String and StringBuffer
  • Because "Strings" is not an instance of StringBuffer, ClassCastException is thrown.

To avoid this, do not have an array typed to both String and StringBuffer. Select only one. For example:

ArrayList<StringBuffer> myArrayList = new ArrayList<StringBuffer>

If you want to copy a String arraylist into a StringBuffer ArrayList, you'll have to iterate over all of the items in z to convert them to string buffers:

ArrayList x=new ArrayList();
ArrayList<String>y=x;
ArrayList<StringBuffer>z=new ArrayList<StringBuffer>();
for(String s : y)
    z.add(new StringBuffer(s));

The reason for this is that StringBuffer does not extent String. What's causing a problem is that you cannot cast a string, say "str" to a StringBuffer i.e. you cannot do StringBuffer s = (StringBuffer)"str";.

To cast ArrayList x to ArrayList<T>, all elements of x must be extend or be an instance of T.

In addition, you should always use generic types, when possible. If you don't know what will be (for example) in the list, use:

ArrayList<?> x = new ArrayList<?>();

If you know a little bit more, such as that it will be a subclass of another class, use ArrayList<? extends T> or ArrayList<? implements T>. This will help you avoid future ClassCastExceptions.

Ryan Amos
  • 5,422
  • 4
  • 36
  • 56