I have 3 classes A, B, and C. The only thing they have in common is a getName() function, nothing else.
I have an array of type Class which stores the above classes.
Class[] classes = {A.class,B.class,C.class};
I then have a List that contains objects of types A, B, and C
List<?> list = new ArrayList<?>();
list.add(new A());
list.add(new B());
list.add(new C());
I want to access the objects in the list through a loop. I also want to access methods of the objects A, B, and C. So, I try casting them using the classes array.
for(int i = 0; i < classes.length;i++)
{
classes[i].cast(list.get(i)).getName(); //A,B,and C have method getName() in common
}
This gives me a compiler error: “The method getName() is not defined for type Object
Is there a way for the compiler to ignore this type of casting until runtime (I am sure it will work at runtime)? Or is there another solution that does what I expect(I am looking for a solution that does not involves changing the code of classes A, B, and C)
An answer is to use the instanceof operator. This seems reasonable if the classes in the List are known. Here is some code:
public static void main(String[] args) { A aObject; B bObject; C cObject; List list = new ArrayList(); list.add(new A()); list.add(new B()); list.add(new C()); list.add(new String()); for (Object current : list) { if (current instanceof A) { aObject = (A)current; System.out.println(aObject.getName()); } else if (current instanceof B) { bObject = (B)current; System.out.println(bObject.getName()); } else if (current instanceof C) { cObject = (C)current; System.out.println(cObject.getName()); } else { System.out.print("Unexpected class: "); System.out.println(current.getClass()); } } }Here is a (slightly) more verbose (then in other answers) example of doing this using Reflection. This seems reasonable if the classes in the List are not known or there are many of them. The commented out line below uses the Apache Commons Lang class MethodUtils.
public static void main(String[] args) { List list = new ArrayList(); Method getNameMethod; list.add(new A()); list.add(new B()); list.add(new C()); list.add(new String()); for (Object current : list) { // getNameMethod = MethodUtils.getAccessibleMethod(current.getClass(), "getName", (Class[])null); try { getNameMethod = current.getClass().getMethod("getName"); } catch (SecurityException exception1) { getNameMethod = null; } catch (NoSuchMethodException exception1) { getNameMethod = null; } if (getNameMethod != null) { try { System.out.println(getNameMethod.invoke(current, (Object[])null)); } catch (IllegalArgumentException exception) { // TODO Implement this catch block. } catch (IllegalAccessException exception) { // TODO Implement this catch block. } catch (InvocationTargetException exception) { // TODO Implement this catch block. } } else { System.out.print("Unexpected class: "); System.out.println(current.getClass()); } } }