Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 431
  • Last Modified:

Custom Class to Object Array and Back

Here is my scenario:

I have an Object[] that has been created from some custom classes. I want to cast the Object[] to an array that is the type of the custom class.  I've tried this and recieve a cast exception.

MyClass[] stuff = (MyClass[])TheObjects[];

I implement the Serializable interface on my custom class as I've seen that mentioned in similar questions.  Any suggestions?

Thanks.
0
mmarksbury
Asked:
mmarksbury
  • 11
  • 8
  • 3
  • +3
4 Solutions
 
CEHJCommented:
That should be

MyClass[] stuff = (MyClass[])TheObjects;
0
 
StillUnAwareCommented:
You can't do that, You'll have to manually recreate the array:

MyClass[] stuff = new MyClass[theOjects.length];
for(int i = 0; i < theObjects.length; i++)
    stuff[i] = (MyClass)theObjects[i];
0
 
mmarksburyAuthor Commented:
CEHJ, my mistake in posting.  It is as you mentioned.

Now, there's got to be a way in Java to convert arrays.  We're talking about only three lines of code, but I want to be able to reuse this without having to duplicate that in all my custom classes.  Any other approaches?  I'm confined to 1.4.2_11
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
CEHJCommented:
Correction - you will have to create a new array and copy the elements over
0
 
StillUnAwareCommented:
Some time ago, I tried to find another way, no success. But hey, maybe there is some reflection or hacking guru, who will find another way.
0
 
fffej78Commented:
Even in Java5 you have the problem that you can't do generic array creation, so a function you might think would work wouldn't e.g.

public static <T> T[] convert( Object[] object )
{
  T[] returnValue = new T[ objects.length ]; // this won't work because of generic array creation.
  // copy across....
}

The best idea I can think of to minimise the amount of effort is two-fold (and you would probably still have to upgrade to Java5 so it's not a really good option ;p)

1) Get rid of arrays, they suck as collection classes, you are better off using a list or set if ordering doesn't matter.
2) Use a strongly-typed collection generator, such as the one available from here http://www.razorsource.com/SourceCutter/GeneratorTemplates.aspx [RazorSource] and just generate strongly-typed collection classes instead.
0
 
mmarksburyAuthor Commented:
Being stuck in 1.4, Strongly Typed Collections are not an option, thus, I'm stuck with my Arrays.  
0
 
fffej78Commented:
If you're stuck with Java 1.4, then as far as I know, you're stuck with the solution StillUnAware mentioned which works, but is butt-ugly and you'll have to create different versions for every type of object you come across.

If you have an editor that supports templates, then you could do that and generate the code as necessary (or just copy and paste, yeuch!). Without generics there is no mechanism to allow you to avoid it.  Someone else suggested reflection, but that's not going to cut the mustard without generics.
0
 
CEHJCommented:
>>
We're talking about only three lines of code, but I want to be able to reuse this without having to duplicate that in all my custom classes.  Any other approaches?
>>

Is it always the same source and target types?
0
 
Mayank SAssociate Director - Product EngineeringCommented:
Try: MyClass[] stuff = Arrays.asList ( TheObjects ).toArray ( new MyClass [] ) ;
0
 
objectsCommented:
you can't do it without recreating the array due to the original array being created as an array of Objects.
You cannot cast an array of Object's to array or what type is actually stored in the array. You need to create a new array as shown by StillUnAware.
0
 
Mayank SAssociate Director - Product EngineeringCommented:
Why not using Collection.toArray () ? Of course the performance hit might be felt....
0
 
fffej78Commented:
Because you'd still end up with an untyped array, as he's using Java 1.4
0
 
Mayank SAssociate Director - Product EngineeringCommented:
Arrays.asList () and toArray () work with 1.4 too, I don't see issues there.
0
 
fffej78Commented:
Arrays.asList() and toArray() both return Object[].  The question is to return some type T[].  You can't cast an array to a different type.
0
 
Mayank SAssociate Director - Product EngineeringCommented:
If you know the overloads for toArray (), there is one method which takes an Object[] array as argument and returns an array of the same type, so you can use:

String[] array = list.toArray ( new String[0] ) ;

if you directly want to get a String[].

http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collection.html#toArray(java.lang.Object[])

Same way in this case you can do: MyClass[] stuff = Arrays.asList ( TheObjects ).toArray ( new MyClass [0] ) ;

It will return a MyClass[]
0
 
Mayank SAssociate Director - Product EngineeringCommented:
>> Arrays.asList() and toArray() both return Object[].  

Arrays.asList () returns a list, you can then apply toArray on the list.
0
 
fffej78Commented:
But you still can't write a generic method.  You just have to keep copying and pasting code all over the place.

MyClass[] stuff = Arrays.asList ( TheObjects ).toArray ( new MyClass [0] ) ;
MyClass2[] stuff = Arrays.asList ( TheObjects ).toArray ( new MyClass2 [0] ) ;

But I guess this is the only option if you are stuck with Java 1.4
0
 
Mayank SAssociate Director - Product EngineeringCommented:
I don't see looping and type-casting to be a generic approach. toArray ( Object[] ) itself is as generic as you need~!
0
 
fffej78Commented:
I agree, looping and type-casting isn't a generic approach, but neither is yours, though it is the only solution in Java 1.4.  A truly generic solution wouldn't involve copying and pasting code everywhere (even if it is just one line of code), but without Java5 you can't avoid that.

In conclusion though I think you've got the right solution.

MyClass[] stuff = (MyClass[])TheObjects[];

should be:

MyClass[] stuff = ( MyClass[] ) Arrays.asList( TheObjects ).toArray( new MyClass[0] );

Don't forget the type-cast!
0
 
Mayank SAssociate Director - Product EngineeringCommented:
>> but neither is yours,

It is, more than anything else suggested on this page. If you were on Java 5, what would you use?

>> A truly generic solution wouldn't involve copying and pasting code everywhere

Its only like a method-call to a utility method so that shouldn't be much of a problem.
0
 
Mayank SAssociate Director - Product EngineeringCommented:
>> Don't forget the type-cast!

The compiler will take care of that, if you try MyClass[] stuff = Arrays.asList ( .... ).toArray ( .... ) ; it is likely to bomb with a compilation error.
0
 
fffej78Commented:
The solution you propose is not a generic solution.  A generic solution is one that doesn't involve cutting and pasting code everywhere.  If you had Java 5 I'd write a method, such as:

public static <T> T[] convert( T[] instance, Object[] array )
{
  return ( T[] ) Arrays.asList( array ).toArray( instance );  
}

I then don't have to paste code everywhere, I've encapsulated the type-cast in one location, rather than splattering it about everywhere.  Your solution is anything but "like a method-call to a utility method", because you have code duplicated in (potentially) hundreds of places.  If your requirements change, how are you going to manage that?  Search and replace?  The advantage of a method is a centralised point, meaning I can change the behaviour in many locations, by editing one line of code, instead of editing 100's of lines of code.  

On the type-cast issue, I was just pointing out that the type-cast needs to be there, it was meant as a support to your statement, not a criticism.  As I said, I think your solution is the right one.  

I get the feeling you are trying to pick an argument, I'm just trying to have a level headed discussion on what a generic solution is and isn't.  All I'm trying to get across is:
1) Saying you have a generic solution is wrong, because you have to cut and paste code everywhere.
2) You are right, however, that this is a correct solution for Java 1.4, because Java1.4 is a horrible mess of a language :)
0
 
Mayank SAssociate Director - Product EngineeringCommented:
>> A generic solution is one that doesn't involve cutting and pasting code everywhere.  If

Its one line of code whether you call toArray () or whether you write your own convert () method and call it.

>> If your requirements change, how are you going to manage that?  Search and replace?

No. It depends on whether you call toArray () directly or encapsulate the call to toArray () in your convert () utility method. Besides, this was not really in the scope of the earlier question.

>> If you had Java 5 I'd write a method,

Ah, now in Java 1.4 too, I think you can write a method to do it, perhaps this way:

public static Object[] convert ( Object[] array, Class targetType )
{
  return Arrays.asList ( array ).toArray ( java.lang.reflect.Array.newInstance ( targetType, 0 ) ) ;

} // end of convert ()

>> Saying you have a generic solution is wrong,

It was initially just a suggestion to use the in-built toArray () which is quite generic itself. Of course the way you want to use it (whether call toArray () 100 times or whether wrap it in another util method of your own is a choice of the developer). But now see the above convert () method, if that is what one wants to use in Java 1.4.

>> I get the feeling you are trying to pick an argument

No.
0
 
fffej78Commented:
The difference between your method and the Java5 method is that you'd still have to have the type-cast everywhere, thus repeating yourself.  As you know, Java5 generics would remove the need to repeat yourself with type-casts everywhere.  I'd disagree that anything in Java1.4 is "generic" because you have to put type-casts in order to make the compiler happy.

A follow-up to the original question stated:

"but I want to be able to reuse this without having to duplicate that in all my custom classes"

I don't think there is a solution that doesn't involve duplicating, because without generics you duplicate the type-cast everywhere.  Maybe I have a lower tolerance for duplication, hence my banging on about what a truly generic solution is.

Since the questioner is stuck with Java 1.4, let's just draw a line under this and leave your solution :)
0
 
Mayank SAssociate Director - Product EngineeringCommented:
Yes, in Java 1.4 you have to type-cast but luckily the compiler will make sure you do it.
0
 
Mayank SAssociate Director - Product EngineeringCommented:
(so there won't be run-time exceptions. of course the only repetition is one small (MyClass[]) but that's unavoidable).
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 11
  • 8
  • 3
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now