Solved

dynamic casting?

Posted on 1998-02-10
15
13,770 Views
Last Modified: 2011-08-18
Is there a way to dynamically cast an object?
I already know that the object valid
and that I have the class name.

  method(Object o) {
     (fill in here)o).afield = 55;
  }
0
Comment
Question by:hank1
  • 6
  • 4
  • 4
  • +1
15 Comments
 
LVL 2

Expert Comment

by:shogi
ID: 1232995
YES!  

class A extends Object
{
  public int afield;
  // ...
}

class B
{
   void method(Object o)
   {
     if (o intanceof A)  // optional, just for protection
     {
         ((A)o).afield = 55;
     }
   }

}

  You can cast if you be sure that your object exist!  And you not force to use the if with the instanceof, but it's a protection and if you know that it's a valid object you can cast it directly.



0
 
LVL 1

Author Comment

by:hank1
ID: 1232996
I mean dynamically as in I don't have (A) until
runtime.  Using instanceof means that I know what
I have and "switch" to the cast I want. The only thing
I know is that any object I get will have a field
named serialNumber, and I want to
((dynamically cast)o).serialNumber = 1231231;
In another way say I pass
a class type-name (how?) along with the mystery object like

  method (class_name, mysteryO)

  then I want to cast
    (class_name)mysteryO

Follow-up ..
Does an 'object' have a way of discovering
its own name - I see something called Object.getClass()
but have no idea how to use it.  Seems like it may be a
way for an upcasted object to downcast itself.


0
 
LVL 2

Expert Comment

by:shogi
ID: 1232997
No, you can't do that like this...but if you use Java 1.1..
java.lang.reflect will help you to do everything you need in run-time.  I put one simple example :


import java.awt.*;
import java.applet.*;
import java.lang.reflect.*;

class A extends java.lang.Object
{
   public int Variable;  
   
   A(int n)
   {
      Variable = n;
   }

}

class B extends java.lang.Object
{
   public int Variable;  
   
   B(int n)
   {
      Variable = n;
   }

}

public class Applet1 extends Applet
{
      public void init()
      {
            // Take out this line if you don't use symantec.itools.net.RelativeURL or symantec.itools.awt.util.StatusScroller
            symantec.itools.lang.Context.setApplet(this);
      
            // This code is automatically generated by Visual Cafe when you add
            // components to the visual environment. It instantiates and initializes
            // the components. To modify the code, only use code syntax that matches
            // what Visual Cafe can generate, or Visual Cafe may be unable to back
            // parse your Java file into its visual environment.
            //{{INIT_CONTROLS
            setLayout(null);
            setSize(426,345);
            label1 = new java.awt.Label("text");
            label1.setBounds(48,12,274,24);
            add(label1);
            button1 = new java.awt.Button();
            button1.setActionCommand("button");
            button1.setLabel("Class A");
            button1.setBounds(24,252,144,68);
            button1.setBackground(new Color(12632256));
            add(button1);
            button2 = new java.awt.Button();
            button2.setActionCommand("button");
            button2.setLabel("Class B");
            button2.setBounds(228,252,141,71);
            button2.setBackground(new Color(12632256));
            add(button2);
            label2 = new java.awt.Label("text");
            label2.setBounds(48,48,278,24);
            add(label2);
            label3 = new java.awt.Label("text");
            label3.setBounds(48,84,288,24);
            add(label3);
            label4 = new java.awt.Label("text");
            label4.setBounds(48,120,288,24);
            add(label4);
            label5 = new java.awt.Label("text");
            label5.setBounds(48,156,288,24);
            add(label5);
            label6 = new java.awt.Label("text");
            label6.setBounds(48,192,288,24);
            add(label6);
            //}}
      
            //{{REGISTER_LISTENERS
            SymMouse aSymMouse = new SymMouse();
            button1.addMouseListener(aSymMouse);
            button2.addMouseListener(aSymMouse);
            //}}
      }

    void TheMethod(Object obj)
    {
        int tVariable=0;
        Class theClass = obj.getClass();
     
        Field ref[] = theClass.getFields();
       
        label1.setText(ref[0].toString());
           
        label2.setText(ref[0].getDeclaringClass().toString());

        label3.setText(ref[0].getName());  
       
        label4.setText(theClass.getSuperclass().getName());

        label5.setText(Modifier.toString(theClass.getModifiers()));
 
        try
        {
          Field result = theClass.getField("Variable");
          tVariable = result.getInt(obj);
        }
        catch(NoSuchFieldException e)
        {}
        catch(IllegalAccessException e)
        {}
        label6.setText("The value tVariable is " + tVariable);
    }

      
      //{{DECLARE_CONTROLS
      java.awt.Label label1;
      java.awt.Button button1;
      java.awt.Button button2;
      java.awt.Label label2;
      java.awt.Label label3;
      java.awt.Label label4;
      java.awt.Label label5;
      java.awt.Label label6;
      //}}

      class SymMouse extends java.awt.event.MouseAdapter
      {
            public void mouseClicked(java.awt.event.MouseEvent event)
            {
                  Object object = event.getSource();
                  if (object == button1)
                        button1_MouseClick(event);
                  else if (object == button2)
                        button2_MouseClick(event);
            }
      }

      void button1_MouseClick(java.awt.event.MouseEvent event)
      {
            A a = new A(65);
        TheMethod(a);

      }

      void button2_MouseClick(java.awt.event.MouseEvent event)
      {
        B b = new B(66);
       
        TheMethod(b);
      }
}

0
 
LVL 1

Author Comment

by:hank1
ID: 1232998
looks good - let me digest it.  I'll get back to you.
Thanks alot!
0
 
LVL 1

Author Comment

by:hank1
ID: 1232999
Seems that reflection methods cannot obtain a friendly
field only public ones, while casting will access friendly
members.  Why do you think they would allowing casting
privledges not allow here?

    Class moClass = mo.getClass();
    if (globalCommand == cmd.moduleSerialNumber) {
      System.out.println("This is a serial number request");
      try {
        Field moField = moClass.getField("moduleSerialNumber");
        moField.set(mo, new String("thisIsATest"));
      } catch (Exception e) {
        e.printStackTrace();
        return false;
      }
      return false;
    }

I cannot allow the objects fields to be public so I'll have
to come up with something else.  Come back and I'll give
you your points.  

ps - any ideas on this?   If not I am going to have to create
a complete list of possible classes passed to this method and
to instance test nuts.
Thanks shogi!


0
 
LVL 3

Expert Comment

by:gwalters
ID: 1233000
If I understand what you're doing, may I suggest using an Interface?  That's what they're there for.

0
 
LVL 2

Expert Comment

by:shogi
ID: 1233001
You can't cast with a variable
{
 method (class_name, mysteryO)
      then I want to cast
  (class_name)mysteryO
}

Interface will not resolve your problem, because you don't know your class before calling.

You unique change it's to use java.lang.reflect,  but if you can allow the field to be public.  The better way it's to add in each  class you have moduleSerialNumber, a method to get it.  And after that you just have to access this method with reflect.

like in your class
 public int getModuleSerialNumber() (return moduleSerialNumber;}

// Naturally here all in try / catch

Method GetRef = TheClass.getMethod("getModuleSerialNumber", TheClass);

Object argGet[] = {};  //empty argument
Integer MymoduleSerialNumber = (Integer) GetRef.invoke(obj, argGet);
int LaValeurModuleSerialNumber = MymoduleSerialNumber.intValue();


0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 3

Expert Comment

by:gwalters
ID: 1233002
shogi:

You obviously don't understand Interfaces.  You say "you don't know your class before calling".  THAT'S THE POINT OF AN INTERFACE.  You don't have to know the class, only that it implements the method you are about to call.
0
 
LVL 1

Author Comment

by:hank1
ID: 1233003
interface? - I'll check it out in this respect. I have only
used interfaces as a design tool - for creating
things like instruments that must impliment methods like
on() off() stop() and go()  - simple stuff that can be passed
around.

I really don't see now
how an interface will work for me and how it will allow me
access to friendly fields.  Thanks for the feedback shogi and
gwalters!  I'LL BE BACK.
0
 
LVL 5

Expert Comment

by:fontaine
ID: 1233004
You have to use interfaces, indeed.

Example:

// definition of the interface

public interface myInterface
{
 public String getMessage();
}

---

// two examples of classes implementing the interface

public class A implements myInterface
{
 ...

 public String getMessage()
 {
  return "Message from A";
 }
}

public class B implements myInterface
{
 ...

 public String getMessage()
 {
  return "Message from B";
 }
}

Now, dynamic casting...

void method(Object o)
{
// the following line performs the casting. As both A and B
// implements myInterface, the "cast" will succeed. Otherwise,
// it will fail.

 myInstance i = (myInstance)o;

 String message = i.getMessage();

// for A, you will have "Message from A"
// for B, you will have "Message from B"

 System.out.println(message)

 return;
}

0
 
LVL 1

Author Comment

by:hank1
ID: 1233005
I understand how an interface guarantees a static cast but I
don't see how it helps in accessing a friendly field dynamically.
If all my classes impliment X, then I'll be ok. But all the
classes don't. I really only
know one thing - they have a friendly field.
I think I am with shogi and believe it cannot be done.

Again, it is strange as to why access privileges differ
between a 'static' cast operation (MyKnownClassType)o and
a 'dynamic' cast using Class and Field methods in my
example above.
Still working it but about ready to surrender.
Thanks for the feedback!

0
 
LVL 3

Expert Comment

by:gwalters
ID: 1233006
You can't use an interface to access a variable (what you call a friendly field), only a method.

You need to have your interface include two methods:

Object getAField()
void setAField(Object)

It's slightly less efficient than accessing the variable directly, but it allows you to do what you want and it's better programming.

The other alternative is to have all your classes extend a single class, which contains the variable you want access to.  The problem here is that they may not extend any other class (no multiple inheritance in Java).
0
 
LVL 1

Author Comment

by:hank1
ID: 1233007
I have the advantage that all the classes belong to the
same package.
 
Ok, I surrender!  For some unknown reason the the Class and Field
version of my dynamic cast attempt will not allow access
where a 'static' cast will.  I've tried everything I
know.  Thankyou all for your help.   He was first, so,
shogi come back and get you points.
0
 
LVL 2

Accepted Solution

by:
shogi earned 50 total points
ID: 1233008
I pass GO and grab the points :-)

You best solution it's with reflect, direct access to public variable or method, and it's work very well ... But sorry none for friendly field...



 
0
 
LVL 3

Expert Comment

by:gwalters
ID: 1233009
As long as I never have to maintain any of your code, do whatever you want.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…

707 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

13 Experts available now in Live!

Get 1:1 Help Now