Link to home
Start Free TrialLog in
Avatar of RayLeong
RayLeong

asked on

returning object[] of a specific type

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?


Avatar of Mick Barry
Mick Barry
Flag of Australia image


Object[] result = Array.newInstance(itemClass, n);
Listening...
Avatar of Ovi
Ovi

You can achive'it as your in your code.
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);
    }
  }
}
Avatar of RayLeong

ASKER

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.





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
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.
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
RayLeong,

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

Cheers,
Ken
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
ASKER CERTIFIED SOLUTION
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
No offence taken :)