Link to home
Start Free TrialLog in
Avatar of maddy051398
maddy051398

asked on

Calling all OO gurus

Can I generate a type cast given only a string containing a class name.

eg if I want to do

TypeA anA = (TypeA)anObjectInputStream.readObject()

can I do this given
String class_name = "TypeA"

I tried
anA = (Class.forName(class_name))anObjectInputStream.readObject()
but that didn't work, strangely!

Any suggestions?
Regards,

Maddy.
Avatar of dryang
dryang



   eg if I want to do

>>   TypeA anA = (TypeA)anObjectInputStream.readObject()

This is OK

>>   can I do this given
>>  String class_name = "TypeA"

Nope! you will just get a String Object, class_name with the value "TypeA"

>>   I tried
>>  anA = (Class.forName(class_name))anObjectInputStream.readObject()
>>   but that didn't work, strangely!

Not strange at all.
1) class_name is a String Object
2) Class.forName is not the same as TypeA - unless Class.forName has the capability to take in a String object and use the String Object value to change its class type (which I doubt it can do)

therefore you are still stuck with
 TypeA anA = (TypeA)anObjectInputStream.readObject()
to do your casting

any futhur questions, just post it here ok?
Avatar of maddy051398

ASKER

Hi,

>> unless Class.forName has the capability to take in a String object and use the String Object value to change its class type (which I doubt it can do)

This was the question I intended! Can I convert a String value to something the compiler will accept as a casting expression.  Not necessarily using Class.forName, that was just the first thing I tried.

So.. how can I put something in a cast expression that isn't a class name?

Regards,

Maddy.
I don't think that's possible. However, if you explained what you are attempting to accomplish, someone may be able to suggest an alternative that will work.

Hi again,

I've just tried to describe the problem without boring you and have given up, suffice to say I've found a way to do what I wanted.

'Simply' put, say I have a base class called Message and a Transmitter class that could receive Message objects - by calling Transmitter.Receive(Message m) - then I wanted to be able to receive all sorts of objects derived from Message without the Transmitter class knowing what they all were.

However ObjectInputStream.readObject(), which I was calling in Transmitter.Receive() needs you to cast to the type you want to receive.

So I got Transmitter.Receive()to call m.GetFrom(stream), implemented in each class derived from Message, passing the ObjectInputStream.  These methods could call stream.readObject()and cast the result to their own types, which they of course know about.

I hope that sounds useful and/or explains my problem.

Regards,

Maddy.
hi maddy,
I see the light now. Good luck to your programming  :)
Hi,

amazing, I managed to explain it!! Now I have the slight problem of not being able to delete this question now I don't need an answer!
Regards,
Maddy.

Here's an answer!  Accept me please!
But I need the 100 points for something useful, probably!
Yes, this is possible.  I've used it before.  The limitation is though is that you need to know exactly what types of parameters the constructor of that class is using.

Let's assume for simplicity that the constructor for class TypeA has no parameters.
Then you can do this nighty trick:

TypeA var = (TypeA)Class.forName("TypeA").getConstructor(null).newInstance(null);

Of course, you need to catch the ClassNotFound exception.

Suppose now that your constructor has one parameter of type string and one parameter of type int[].  Then you'll do this:

Class p1 = Class.forName("String");    //or java.lang.String - I don't remember
Class p2 = Class.forNamr("int[]");

Class[] p = {p1,p2};

String s1 = "hello there";
int[] s2 = {1,2,3,4,5};

Object[] s = {s1,s2};

TypeA var = (TypeA)Class.forName("TypeA").getConstructor(p).newInstance(s);

Again, you need to catch the ClassNotFound exception
Hi,

In the line...
TypeA var = (TypeA)Class.forName("TypeA").getConstructor(null).newInstance(null);

you've got a cast to TypeA.  This is the bit I need(ed) to avoid.  Say I only know about an interface eg 'AnInterface' that 'TypeA' implements (this stuff is in a separate class that knows nothing about the actual types, only about 'AnInterface' objects)

I want(ed) to do...

AnInterface x = (TypeA)anObjectInputStream.readObject()

but without knowing the type of the derived class.

I guess there's no way to do a cast without having the actual Class name to cast to directly in the code.

So I did...

theMethod ( AnInterface x )
{
   // get the object input stream
   ...

   x.getFrom ( anObjectInputStream ) ;
}

where getFrom() is implemented in class TypeA and knows what to cast the return value of readObject() to.

Regards,

Maddy.
When you're doing the cast, you don't need to have the class name in the cast type.
Suppose you have something like this:

public interface MyInterface;
public class MyClass implements MyInterface;

Object obj;

Then you can do something like this:
MyInterface mi = (MyInterface)obj;

This along with my previous answer should give you what you need.
Casting to the base Interface class means ObjectInputStream.readObject() doesn't get the correct (derived) object data from the stream.

Maddy
ASKER CERTIFIED SOLUTION
Avatar of threshold
threshold

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
Here is one concept of Java Program:

Who wants to use/invoke the Object = Who knows the information of the Object = Who re-cast the Object.

so... You re-cast it when you use it!

Hope it will clarify something more.
So what I wanted to do wasn't possible, but now there's a lot of information here that may be useful.

Thanks,
Maddy.