Solved

Custom Class to Object Array and Back

Posted on 2006-06-20
29
424 Views
Last Modified: 2008-02-01
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
Comment
Question by:mmarksbury
  • 11
  • 8
  • 3
  • +3
29 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 16943663
That should be

MyClass[] stuff = (MyClass[])TheObjects;
0
 
LVL 14

Expert Comment

by:StillUnAware
ID: 16943668
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
 
LVL 7

Author Comment

by:mmarksbury
ID: 16943694
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.

 
LVL 86

Accepted Solution

by:
CEHJ earned 125 total points
ID: 16943707
Correction - you will have to create a new array and copy the elements over
0
 
LVL 14

Expert Comment

by:StillUnAware
ID: 16943712
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
 
LVL 4

Expert Comment

by:fffej78
ID: 16944083
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
 
LVL 7

Author Comment

by:mmarksbury
ID: 16944649
Being stuck in 1.4, Strongly Typed Collections are not an option, thus, I'm stuck with my Arrays.  
0
 
LVL 4

Expert Comment

by:fffej78
ID: 16944835
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
 
LVL 86

Expert Comment

by:CEHJ
ID: 16944861
>>
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
 
LVL 30

Expert Comment

by:Mayank S
ID: 16948766
Try: MyClass[] stuff = Arrays.asList ( TheObjects ).toArray ( new MyClass [] ) ;
0
 
LVL 92

Assisted Solution

by:objects
objects earned 125 total points
ID: 16948832
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
 
LVL 30

Assisted Solution

by:Mayank S
Mayank S earned 125 total points
ID: 16948838
Why not using Collection.toArray () ? Of course the performance hit might be felt....
0
 
LVL 4

Expert Comment

by:fffej78
ID: 16948928
Because you'd still end up with an untyped array, as he's using Java 1.4
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 16949054
Arrays.asList () and toArray () work with 1.4 too, I don't see issues there.
0
 
LVL 4

Expert Comment

by:fffej78
ID: 16949071
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
 
LVL 30

Expert Comment

by:Mayank S
ID: 16949086
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
 
LVL 30

Expert Comment

by:Mayank S
ID: 16949090
>> Arrays.asList() and toArray() both return Object[].  

Arrays.asList () returns a list, you can then apply toArray on the list.
0
 
LVL 4

Expert Comment

by:fffej78
ID: 16949108
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
 
LVL 30

Expert Comment

by:Mayank S
ID: 16949123
I don't see looping and type-casting to be a generic approach. toArray ( Object[] ) itself is as generic as you need~!
0
 
LVL 4

Expert Comment

by:fffej78
ID: 16949405
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
 
LVL 30

Expert Comment

by:Mayank S
ID: 16949776
>> 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
 
LVL 30

Expert Comment

by:Mayank S
ID: 16949782
>> 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
 
LVL 4

Assisted Solution

by:fffej78
fffej78 earned 125 total points
ID: 16949970
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
 
LVL 30

Expert Comment

by:Mayank S
ID: 16950071
>> 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
 
LVL 4

Expert Comment

by:fffej78
ID: 16950116
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
 
LVL 30

Expert Comment

by:Mayank S
ID: 16950156
Yes, in Java 1.4 you have to type-cast but luckily the compiler will make sure you do it.
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 16950161
(so there won't be run-time exceptions. of course the only repetition is one small (MyClass[]) but that's unavoidable).
0

Featured Post

Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
ejb wildfly example 2 29
Notify sent to other threads in Java 9 34
swing controls 2 16
spring maven example issues 3 13
An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.

820 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question