3

I have a method which accepts an Object. The object is a list. The list could be any type. I would like to identify the type of list using reflection and create an instance of the list & iterate over it and print the results.

Different Types of List

List<Customer> customerList = new ArrayList<Customer>();
List<Service> serviceList = new ArrayList<Service>();
List<Product> productList = new ArrayList<Product>();

Method that accepts the list

public void printList(Object genericList){

// identify the type of list
// create the list object
// iterate over the list and print the values

}
1
  • I have a few clarification questions: 1. When you say "identify the type of list" do you mean identify whether it is an ArrayList, LinkedList, etc. or identify if the contained type is a Customer, Service, Product, etc. 2. When printList() creates the new list, does is have to be the same class as the genericList? For example, if genericList is an instance of ArrayList, can a variable called newList be an instance of LinkedList? 3. When "iterating over the list to print values" are you expecting that we iterate over the newList or the genericList? Commented Jan 12, 2016 at 18:51

4 Answers 4

4

Because of type erasure, there's no way to tell the generic type of a collection at runtime (which incidentally makes Object genericList an oxymoron). But if you just want to print them out regardless of the type, you can just cast it to List<?>:

public void printList(Object obj){
    for (Object o : (List<?>)obj) {
        System.out.println(o.toString());
    }
}

If you need a more type-specific implementation, and you know the lists won't be empty, and you're confident that there's no overlap between list types (i.e. customerList cannot contain Products and vice-versa), then you can technically do something like this:

public void printList(Object obj){
    List<?> list = (List<?>)obj;
    Object firstElement = list.get(0);
    if (firstElement instanceof Customer) {
        printCustomers((List<Customer>)list);
    } else if (firstElement instanceof Product) {
        printProducts((List<Product>)list);
    } //...
}

Note that the compiler will complain about these casts, and for good reason. It has no way of knowing whether you're telling the truth about the generic type, at least not until you try reading a value from the list, at which point you'll get a ClassCastException if you've made a mistake.

Sign up to request clarification or add additional context in comments.

3 Comments

Can't ParameterizedType be used to identify the type ? If it can't be , assuming I have a way to identify the type , is it possible to recreate the object ?
@PunterVicky it can't. And if you're trying to create a type at runtime, there's no custom construction required. You can just cast it to any generic type you want, because the runtime environment doesn't know about your generic parameters. See my update.
You could use a covariant List if Customer,Product,Service all inherit from the same class i.e. BaseClass and replace the code to List<? extends BaseClass> list = (List<? extends BaseClass>)obj;
1

If you want to judge the data type of the object from a list and print out the value, I would like to say that judging might not need the reflection since instanceof would satisfy your need. To print out the value or to have more manipulations on the specific object you could use the java reflection. It's very fragile. Currently I just list the codes of a simple model. If you confirm this is what you need then we could discuss more.

public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException{

    List<Customer> customerList = new ArrayList<>();
    List<Service> serviceList = new ArrayList<>();
    List<Product> productList = new ArrayList<>();
    List result = returnFunc();
    printList(result);

}


public static void printList(List genericList) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
    Object obj=null;
    String type = "";
    Class c1 = null;
    // identify the type of list
    if(genericList.get(0) instanceof Customer){
        c1 = Class.forName("Customer");
    }else if(genericList.get(0) instanceof Service){
        c1 = Class.forName("Service");
    }else if(genericList.get(0) instanceof Product){
        c1 = Class.forName("Product");
    }else{
        System.out.println("Error");
    }
    // create the list object
    Object instance = c1.newInstance();
    // iterate over the list and print the values
    for(Object o : genericList){
        System.out.println(o.toString());

    }
}
//to randomly output a list
public static List returnFunc(){
    ArrayList<List> tmp = new ArrayList<>();
    ArrayList<Object> list_customer = new ArrayList<>();
    list_customer.add(new Customer());
    ArrayList<Object> list_service = new ArrayList<>();
    list_service.add(new Service());
    ArrayList<Object> list_product = new ArrayList<>();
    list_product.add(new Product());
    tmp.add(list_customer);
    tmp.add(list_service);
    tmp.add(list_product);
    Random r = new Random();
    return tmp.get(r.nextInt(3));
}

Comments

0

create interface and each class implement this interface that is,

public interface someInterface{
}


public class Customer implements someInterface{
}

etc...

2 Comments

Thank you. These are classes provided as part of a jar file. I would like to dynamically identify the type of list and recreate the list.
No I would like to identify the type ( generic type) of list using reflection and once it is identified would like to recreate the object , iterate over the object , determine the fields using reflection and print the values
0

Maybe this is not the best method, but it might get you there

try{ 
    List<Customer> list = (List<Customer>) genericList; 
    list.get(0).methodOfCustomer(); 
    isCustomer = true;}
catch(Exception e){
    isCustomer = false
}

And similar clauses for the rest.

In the end just test which of the boolean is true, or use any other way.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.