Solved

Calling all OO gurus

Posted on 1998-07-22
15
175 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
 

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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

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 100 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

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Suggested Solutions

Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Viewers learn about the “while” loop and how to utilize it correctly in Java. Additionally, viewers begin exploring how to include conditional statements within a while loop and avoid an endless loop. Define While Loop: Basic Example: Explanatio…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:

708 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now