mounaim
mounaim

Reputation: 1180

java.util.ArrayList cannot be cast to java.util.Vector

I'm trying to fill tableModel with data from a list of lists of Objects readExcel.readSheet(0), using following code :

 TableModel tableModel = new DefaultTableModel(
    new Vector<List<Object>>(readExcel.readSheet(0)
       .subList(1, readExcel.readSheet(0).size())), 
    new Vector<Object>(readExcel.readSheet(0).get(0)));  

but I'm getting this exception

java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.Vector  

I think it's about instanciating a Vector via a list, but through javadoc of Vector, we can see it's possible to instantiate a Vector using a collection.

What's the problem with my code snippet ?

Upvotes: 0

Views: 11723

Answers (3)

arcy
arcy

Reputation: 13153

"cast" is an instruction from the programmer to the compiler; it says "it is theoretically possible that the type I am passing here is not a subtype of the required type, but I know that it will be at runtime, so do not give an error saying that this is the wrong type."

The compiler can only cast one type to another if the two types are in an inheritance line together, i.e. if they are inherited, directly or indirectly, one from another.

So I'm going to guess that one of the arguments in your somewhat convoluted constructor and/or method calls requires an ArrayList, and you are passing a Vector. If the constructor or method requires an ArrayList, you cannot pass a Vector to it.

Upvotes: 2

Hirak
Hirak

Reputation: 3649

You can cast a superclass into subclass and vice versa.

But Vector and ArrayList doesn't share any parent-child relationship.

Both have common ancestor though (List > Collection >iterable).

So you can cast a vector to and from a List. But cannot cast to arrayList directly. E.g.

public class test {

static class Foo {

}

static class Moo extends Foo {

}

/**
 * @param args
 */
public static void main(String[] args) {

    List<Moo> list = new ArrayList<Moo>();
    for(int i=0; i<10; i++){
        list.add(new Moo());
    }

    List<Foo> listFoo = (List<Foo>) list;

}

}

Generates a complier error because List is not a sub type of List

So your code should work if you replace Vector> with >

Upvotes: 1

phil_20686
phil_20686

Reputation: 4080

I am not completely sure, but I think the answer is that generics do not respect sub types. E>g. if B extends A, then you might think that you can cast List[B] to List[A], but I think that you actually cannot. Although you can addAll to put all the items from list into list.

Thus

List<ArrayList<Object>> 

is not a type of

List<List<Object>>

and the cast fails because the return type of readExel is the former not the latter.

The reasons for this are mostly to do with obscure edge cases. THere is an item about it in Effective Java

public class test {

static class Foo {

}

static class Moo extends Foo {

}

/**
 * @param args
 */
public static void main(String[] args) {

    List<Moo> list = new ArrayList<Moo>();
    for(int i=0; i<10; i++){
        list.add(new Moo());
    }

    List<Foo> listFoo = (List<Foo>) list;

}

}

Generates a complier error because

List<Moo> 

is not a sub type of

List<Foo>

So your code should work if you replace

Vector<List<Object>> 

with

Vector<ArrayList<Object>>

Upvotes: 1

Related Questions