[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

Calling all OO gurus

Posted on 1998-07-22
15
Medium Priority
?
184 Views
Last Modified: 2012-05-04
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.
0
Comment
Question by:maddy051398
  • 7
  • 2
  • 2
  • +3
15 Comments
 
LVL 1

Expert Comment

by:dryang
ID: 1227498


   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?
0
 

Author Comment

by:maddy051398
ID: 1227499
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.
0
 
LVL 16

Expert Comment

by:imladris
ID: 1227500
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.

0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 

Author Comment

by:maddy051398
ID: 1227501
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.
0
 
LVL 1

Expert Comment

by:dryang
ID: 1227502
hi maddy,
I see the light now. Good luck to your programming  :)
0
 

Author Comment

by:maddy051398
ID: 1227503
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.

0
 

Expert Comment

by:ronaldyang
ID: 1227504
Here's an answer!  Accept me please!
0
 

Author Comment

by:maddy051398
ID: 1227505
But I need the 100 points for something useful, probably!
0
 
LVL 2

Expert Comment

by:shchuka
ID: 1227506
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
0
 

Author Comment

by:maddy051398
ID: 1227507
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.
0
 
LVL 2

Expert Comment

by:shchuka
ID: 1227508
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.
0
 

Author Comment

by:maddy051398
ID: 1227509
Casting to the base Interface class means ObjectInputStream.readObject() doesn't get the correct (derived) object data from the stream.

Maddy
0
 
LVL 2

Accepted Solution

by:
threshold earned 400 total points
ID: 1227510
I have create this sample for you:
public static void main(String args[]) {
      File file = new File("c:\\temp\\vector.test");
      try {
            ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream(file));
            os.writeObject(new java.util.Vector());
            os.close();

            ObjectInputStream is=new ObjectInputStream(new FileInputStream(file));
            Object obj=is.readObject();
            String name=obj.getClass().getName();
            is.close();
            System.out.println(name);
      } catch (Exception e) {
            System.out.println(e);
      }            
}

The Output is "java.util.Vector".
Although I use "Object obj=is.readObject()", I can get the original class name 'java.util.Vector' from it.
I know you try to invoke any methods or any fields from Objects of any Class.
But with the restriction of Java Language, It's very hard to code it, because the Class type is difined in run-time!

We hope we can do that:
         anA = (Class.forName(class_name))anObjectInputStream.readObject();
         anA.methodA();
It can't be compiled, because the compiler can't know the methodA() is legal or not.

If your serialized Object have a common super Class or Interface, you can invoke the common methods of them.
        MyInterface obj= (MyInterface) anObjectInputStream.readObject();
Of cause, the better code should be:
        Object obj= anObjectInputStream.readObject();
        if (!(obj instanceof MyInterface)) throw new MyException;
        MyInterface myobj=(MyInterface)obj;
If they have no common super Class or Interface, your Object will be useless for programs that invoke them.
If we don't know what methods supported by this object, how do we use it?
Why the INVOKER has to invoke a method of a object? The INVOKER have to know what the method does/means.

Maybe you want to create an Object Database for Java, you need to store/use the object with the maximum flexibility.
And maybe the Interface name will need to be defined in run-time... Here is my proposal:
1. To check/view the Class/Field/Method name of arbitrary object, we should use the java.lang.reflect.* package.
2. To invoke the Methods of arbitrary object, the database should return object as Object to db client, and let client re-cast the object and invoke the methods.
3. To access the Fields, you can do it with the 2 ways above.

Here is a simple example with java.lang.reflect.*
        Object obj=(Object) anObjectInputStream.readObject();
        Class class=obj.getClass();
        String class_name=class.getName(); // you can get the name of the class
        Method[] methods=class.getMethods(); // you can get definitions of all methods of the class
        Method method0=methods[0]; // get the first method
        Class[] paraClasses=method0.getParameterTypes(); // get the class type of the method.
        // ..........
Of cause, if you get enough information , you can invoke the methods dynamically!
But it's not easy and not efficient for programming.
Take a look at the package java.lang.reflect.*   you will get all information that you need.
0
 
LVL 2

Expert Comment

by:threshold
ID: 1227511
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.
0
 

Author Comment

by:maddy051398
ID: 1227512
So what I wanted to do wasn't possible, but now there's a lot of information here that may be useful.

Thanks,
Maddy.
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

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

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
Suggested Courses
Course of the Month11 days, 8 hours left to enroll

640 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