tags:

views:

73

answers:

5

I have a List<?> listin Java. Is there a way to determine the type of the contents of that list at runtime when the list is empty?

A: 

Assuming there's at least one object in the list, to get the type of the list - list.get(0).getClass().getSuperclass.getName();

To get the type of an individual object - list.get(0).getClass().getName();

froadie
Depending on what is actually desired, `getClass()`, may not work. A `List<Animal>` may contain a `Dog`, but it's not a `List<Dog>`.
polygenelubricants
@polygenelubricants - true, updating...
froadie
I would like to be able to do this on an empty list. Question edited.
tob
That's good, but it gets the class of the *first* element.
The Alchemist
A: 

Yes, there is. You can iterate over each object in the list, and call the .getClass() method and print out its classname (or do various things based on the class it is).

e.g.,

for (Object o : list) {
   if (o.getClass().equals(MyClass.class)) {
      MyClass myClass = (MyClass) o;
      //do something with myClass etc etc
   }
   //...more if statements?
}
Chii
I would like to be able to do this on an empty list. Question edited.
tob
type erasure will prevent the info you from getting the info you want to obtain at runtime.
Chii
A: 

As Chii says, you can iterate over each element. Other than that, you can't know because technically you can put any object in a List.

e.g.,

    List list = new ArrayList();
    list.add(new Integer(1));
    list.add(new Integer(2));
    list.add("string");
    list.add(new Double(0.2));

In the above example, what would the type of list be? There isn't an answer to that question.

The Alchemist
o alquimista: `tob` is asking for generics. According to generics: Once you have mentioned that the list can hold instance of x then your list can not have instance of y
Rakesh Juyal
@Rakesh: it _can_ if you ignore warnings, use raw types/unchecked conversion, etc. That's precisely why you shouldn't, but you can, if you really want to, or by accident.
polygenelubricants
A: 

If the list is not empty then froadie is correct but if the list is empty then according to Type erasure it is impossible to find the type of object a List can have.

In java,

ArrayList<Integer> li = new ArrayList<Integer>();
ArrayList<Float> lf = new ArrayList<Float>();
if (li.getClass() == lf.getClass()) // evaluates to true
  System.out.println("Equal");

Source: http://en.wikipedia.org/wiki/Generics_in_Java#Type_erasure

Rakesh Juyal
+2  A: 

Unfortunately, you can't figure out the type due to erasure -- in fact, even if the list is not empty you still can not reliably determine what the what the list really is.

Let's say right now your List<?> contains 2 elements: a Double and and Integer ... it would be nontrivial to figure out that it might be a List<Number> ... and even then, it may really be a List<Object> and someone could add a String later.

Furthermore, let's say it's really a List<List<String>>. The most you'll figure out without attempting to recurse is that it's a List<List<?>>.

There is a bright side . Depending on your situation, you may be able to use Type Tokens to work around erasure in a typesafe way. There's a great post here: http://gafter.blogspot.com/2006/12/super-type-tokens.html

Michael D