2

I have a program where I need to find all instances of a class within an array. I would like to create a method that does this for me. For instance, if I have the array

Object[] arr = {"mystring", new Boolean(false), new Integer(4), new Character('i')}

and I called this method with argument of String (I'm not sure what the type of my argument should be, actually), it would return an array of {"mystring"}.

I've tried things like

public void printInstancesOf(Class c, Object[] array)
{
    for (Object obj : array)
    {
        if (obj instanceof c)
        {
             System.out.println(obj);
        }
    }
}

But that doesn't even compile. Does anyone know how to do this? Or is it not possible to do?

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
ucarion
  • 751
  • 2
  • 8
  • 15
  • what do you want to do with the instances? Just print them? – Jeshurun Jun 20 '12 at 03:26
  • possible duplicate of [Is there something like instanceOf(Class> c) in Java?](http://stackoverflow.com/questions/949352/is-there-something-like-instanceofclass-c-in-java) – Brendan Long Jun 20 '12 at 03:29

4 Answers4

6

Looks like you want Class.isInstance(Object o):

Determines if the specified Object is assignment-compatible with the object represented by this Class. This method is the dynamic equivalent of the Java language instanceof operator. The method returns true if the specified Object argument is non-null and can be cast to the reference type represented by this Class object without raising a ClassCastException. It returns false otherwise.

if (c.isInstance(obj) {
    System.out.println(obj);
}
Brendan Long
  • 53,280
  • 21
  • 146
  • 188
  • 1
    Alternatively, you can detect subclasses by trying to cast using `try{ c.cast(obj); System.out.println(obj); } catch (ClassCastException e) {}` – Wug Jun 20 '12 at 03:31
2

That doesn't work since it's testing if obj is an instanceof the literal c class. I don't have a Java environment handy, but I believe something like

if (obj.getClass().equals(c)) {

should do the trick. This probably doesn't work with subclasses though, but that shouldn't be an issue here.

Edit: as others have pointed out

if (c.isInstance(obj)) {

is the better choice

The larger question is...why are you doing this? Trying to simulate loose typing in Java is an admirable goal but usually a very bad idea. Use proper polymorphism and/or generics instead (with custom classes).

tsm
  • 3,598
  • 2
  • 21
  • 35
1

It doesn't look like idiomatic Java. You would normally only build arrays for specific classes and not mix different classes like String, Boolean, Integer, Character.

This is normally a code smell.

If you have a hierarchy like

AFoo, BFoo, CFoo -> extending Foo, and have them in an Array, you would make them react significantly to a message:

for (Foo foo : foos) 
    foo.react (param); 

AFoos could then react in another way than BFoos. Else use instanceof:

for (Foo foo : foos) 
    if (foo instanceof BFoo)
        barDoSomethingWith (foo, param);  
user unknown
  • 35,537
  • 11
  • 75
  • 121
0

Have you tried:

private <E> List<E> findInstances(Class<E> type, Object[] arr) {
    List<E> instances = new ArrayList<E>();
    for(Object o : arr) {
        if(type.isInstance(o)) {
            instances.add((E)o);
        }
    }
    return instances;
}
Jeshurun
  • 22,940
  • 6
  • 79
  • 92