We help IT Professionals succeed at work.

returning object[] of a specific type

RayLeong
RayLeong asked
on
I have a interface
  Object[] getItems(Class itemClass) { }

I wanted the caller to be able to cast the Object[].
  ItemA[] objsA = (ItemA[]) objItem.getItems(ItemA.class);
  ItemB[] objsB = (ItemB[]) objItem.getItems(ItemB.class);

How can I achive this?


Comment
Watch Question

Mick BarryJava Developer
CERTIFIED EXPERT
Top Expert 2010

Commented:

Object[] result = Array.newInstance(itemClass, n);
CERTIFIED EXPERT

Commented:
Listening...
Ovi

Commented:
You can achive'it as your in your code.
Ovi

Commented:
Sorry my mistake, is not possible like your code, but like this :

public class ArrayCast {
  protected String field1;
  protected int field2;
  protected boolean field3;

  public static Object[] getArray(int size) {
    Object[] objects = new Object[size];
    for(int i = 0; i < objects.length; i++) {
      ArrayCast obj = new ArrayCast();
      obj.field1 = String.valueOf(i);
      obj.field2 = i;
      obj.field3 = true;
      objects[i] = obj;
    }
    return(objects);
  }
  public static void main(String[] args) {
    Object[] o = ArrayCast.getArray(10);
    ArrayCast[] objects = new ArrayCast[o.length] ;
    for(int i = 0; i < o.length; i++)
      objects[i] = (ArrayCast) o[i];
    System.out.println("Total elements : " + objects.length);
    for(int i = 0; i < objects.length; i++) {
      System.out.println("Object : " + i);
      System.out.println("Field1 : " + objects[i].field1);
      System.out.println("Field2 : " + objects[i].field2);
      System.out.println("Field3 : " + objects[i].field3);
    }
  }
}

Author

Commented:
objects,

The return type for
    Array.newInstance(itemClass, n);
is Object, and not Object[].



Ovi,
I do not know the type of object to return during compile time. I will only decide it during runtime. Therefore I can't use
    new ArrayCast();
I need something like what objects suggested.





Commented:
RayLeong,

I do not see why your code as written in your question would not work.  I just tried it and it worked for me.  As long as you return an array of Object which has the actual type the same as that to which you are casting, then the cast should work.

Have you tried it?  What was the result when you tried it?

Cheers,
Ken Jones

Author

Commented:
Ken Jones,

Ovi code in a way such that he knows the actual type. In my case, I do not know my actual type till runtime. I want to depend on the input, a Class object or may be something similiar, to construct an array of that type. Then fill it with info and send it back.

Commented:
RayLeong,

You can do dynamic downcasts at run time as long as the downcast is a legal one.  Possibly the example code in the question is misleading.  I assumed from the argument 'Class itemClass' that the caller must a priori know the type of the objects returned in the Object array.

Is the following problem the that you are trying to solve?

Unlike the sample code that you have provide, the caller has no a priori knowledge of what types may be returned.  The returned type may be a type that did not even exist at the time the caller code was written.  

You want the caller to be able to dynamically create objects of types unknown to the caller at the time the caller code was written?  If that is what you are trying to do, then it is an interesting exercise, but I am not certain what the caller will be able to do with the objects beyond what it can do with the Object array (assuming the caller could also have no apriori knowledge of the behavior of an unlimited number of possible object types).

Cheers,
Ken

Commented:
RayLeong,

I think I understand a little now what you are attempting.  Let me give it some more thought.

Cheers,
Ken
Jim CakalicSenior Engineer

Commented:
As indicated by objects, you can use the java.lang.reflect.Array.newInstance method to construct a new array to hold an arbitrary object type. The newInstance method returns an Object because a Java array is in fact a first class Object. For each component type (the thing that the array holds) for which an array can be constructed, there is a corresponding class synthesized by the JVM representing an array that can hold the specified component type (i.e., Class or primitive). To get the returned Object back to a useable array, you must cast it again. If an array holds objects (not primitives) then you can upcast that array object to Object[]. Some examples:

    String[] sarr = (String[])Array.newInstance(String.class, 10);
    int[] iarr = (int[])Array.newInstance(Integer.TYPE, 10);
    Object[] oarr = (Object[])Array.newInstance(String.class, 10);

In the second example, I wanted to create an array of a primitive type int. Since the component type of the array needs to be specified as a Class object, it was necessary to use the corresponding wrapper class TYPE field, in this case Integer.TYPE.

The third example is closest to solving your problem. Your getItems method wouldn't be able to do the downcast dynamically. But it can cast to Object[] assuming that you never need to handle arrays of primitive types:

    public Object[] getItems(Class componentType) {
        int length = ... // figure out the needed array length
        Object[] items = (Object[])java.lang.reflect.Array.newInstance(componentType, length);
        // code to fill the items array here
        return items;
    }

Now the client can downcast the returned Object[] to an array of the specified componentType. I believe that this is what objects meant in his, admittedly terse, response.

Best regards,
Jim Cakalic
Java Developer
CERTIFIED EXPERT
Top Expert 2010
Commented:
> The return type for ... is Object, and not Object[].

As Jim mentions above, an Object[] is an instance of an Object. So the following is valid:

Object[] array = (Object[]) Array.newInstance(itemClass, n);


jim> what objects meant in his, admittedly terse, response.

Yes I do tend to give 'terse' comments sometimes, but I'm also more than willing to elaborate as necessary :-)
Jim CakalicSenior Engineer

Commented:
Didn't mean anything by it. You gave a one-liner that was, except for a required cast, the correct answer to RayLeong's query. You should (and I hope you do) get the points. I, on the other hand, have never been accused of being terse. Too often, I ramble on and on and its a wonder that anyone ever makes sense of what I say. :-o
Mick BarryJava Developer
CERTIFIED EXPERT
Top Expert 2010

Commented:
No offence taken :)

Explore More ContentExplore courses, solutions, and other research materials related to this topic.