aspose file tools
The moose likes Java in General and the fly likes How to dynamically cast an Object  ? Big Moose Saloon
  Search | Java FAQ | Recent Topics
Register / Login
JavaRanch » Java Forums » Java » Java in General
Reply Bookmark "How to dynamically cast an Object  ?" Watch "How to dynamically cast an Object  ?" New topic
Author

How to dynamically cast an Object ?

Laurent Salse
Greenhorn

Joined: Nov 07, 2004
Posts: 14
Dear all,

Here is the situation :

1-I am working with an abstract SuperClass 'Data'
2-Every JavaBean backing my web pages extends 'Data'(User, Client, Product, ...)
3-I am using "generic" methods from 'Data' to interact between web pages and the DataBase through the JavaBeans.

Here is my problem (I guess it is a very classic one !):

When I execute a query from a web Page to the DataBase, the real type of the 'javaBean' is found with "data.getClass()" (it gives User or Client or Product according to the 'JavaBean' in use in the web page).

As a result the instantiated 'Object' MUST BE CASTED into the correct type (the same data.getClass()) to create the correct JavaBean in the context to support the web page !

I can't find any way in the API (Beans, Introspector, Class ...) to cast dynamically the object got from the database ...

Is that possible to do ?
Thanks for any hint that could help !!

Laurent
Steve Morrow
Ranch Hand

Joined: May 22, 2003
Posts: 657

MUST BE CASTED
I don't understand why. If you're returning a bunch of Data objects to the page, what does the underlying implementation matter?
Ryan McGuire
Ranch Hand

Joined: Feb 18, 2005
Posts: 945
Once you create an object of one type, you can't cast as a more specific type.

e.g. Data extends Object. User extends Data. If you declare on object of type Object and set it to be a Data, you can't cast it as a User.



In "((Data)o).getDBName()", you need that second set of parentheses so that the (Data) type cast gets applied to the variable o, not the value returned by o.getDBName().

However, what you may be looking for is a way to make more instances of the class of an existing object.



Of course, you don't need to do this in a separate method.

If all you have is a String that contains either "User" or "Product", etc. you can use Class.forName() to get the Class object in the code above:



You may have to do something clever to include the package name.

Cool?
[ June 29, 2005: Message edited by: Ryan McGuire ]
Laurent Salse
Greenhorn

Joined: Nov 07, 2004
Posts: 14
Cool ?! Of course Ryan ! Thanks a lot for such a complete answer ; that's kind of a real job ! But ...

That does not solve the issue ... let's try beeing clearer !

I am developping a PoC apps integrating JSF+SPING(for AOP)+Hibernate.

Here the generic method I am implementing for DataBase 'SELECT' queries :


public static void select(Data data)throws ClassNotFoundException{

// check the type of the JavaBean in argument ... just to be sure !!!
System.out.println (data.getClass().toString());

/*
Execute a 'SELECT' on the DataBase in the Spring/Hibernate way with the generic arguments 'data.getClass()'and 'data.getId()' !
*/
Object target = ApplicationContextImpl.getHibernateTemplate().
load(data.getClass(), new Integer(data.getId()));

// cast the 'result' into the expected JavaBean type ... just because the 'load' method needs it I guess !

User user = (User)target;

// check the result ...
System.out.println(user.getId() +" "+ user.getName() + " "+ user.getLastName);

This works perfectly well ! But It is a 'quick & durty' workaround : I would like to make "User user = (User)target; " more generic with the help of "data.getClass()" because this is the Class I want to cast 'target' into ...

Someone said I'm a dreamer ?
Laurent Salse
Greenhorn

Joined: Nov 07, 2004
Posts: 14
just a piece of aditionnal information : my 'quick & durty' workaround works because the JavaBean I use for testing is a User (extending Data).

Therefore, the 'select(Data data)' method receives a User as an argument !

Arguments 'User.class' and an Integer 'ID' are passed to the 'load()' method.

Then, the 'load()' method selects the User with the corresponding ID from the Database through the Hibernate mapping relationship !

Finally, I can cast the resulted object ('Target') into User ... because I know it is one ;-)

If the load() method could have done the job, I would have appreciated, but ...
Ryan McGuire
Ranch Hand

Joined: Feb 18, 2005
Posts: 945
Since data is a Data or some subclass, you can be sure that load() returns a Data. So you can cast the return value of load() to a Data right in the same line. But then you don't know what specific Data (User, Product, etc.) you have, so you don't know what to print out. This should be delegated to the returned object itself:



Then define checkTheResults() (perhaps abstract) in Data and override it in the subclasses.

in Data:


in User:


There's no need to use target.getClass() to select what type of functionality to use. That's exactly what polymorphism is for.

[Edit: removed "abstract" from the User code snippet.]
[ June 29, 2005: Message edited by: Ryan McGuire ]
Ryan McGuire
Ranch Hand

Joined: Feb 18, 2005
Posts: 945
Originally posted by Ryan McGuire:
Since data is a Data or some subclass, you can be sure that load() returns a Data. So you can cast the return value of load() to a Data right in the same line.


I assume that load() is declared to return an Object. In that case you may want to wrap this call to load in a try/catch block to catch a ClassCastException just in case load() returns an object that can't be cast to a Data. If load() is declared to return a Data, then the compiler should enforce that restriction so that you don't have to worry about the class cast.

You might also want to watch out for NullPointerExceptions.
Laurent Salse
Greenhorn

Joined: Nov 07, 2004
Posts: 14
That's the kind of a solution I thought I would have to turn to ...

Thanks a lot Ryan for the details ... I am making it exactly as you say !

Definitely coool !
Steve Morrow
Ranch Hand

Joined: May 22, 2003
Posts: 657

There's no need to use target.getClass() to select what type of functionality to use. That's exactly what polymorphism is for.
That's the point I was trying to make (ineffectually) in my first response. Good explanation!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: How to dynamically cast an Object ?
 
Similar Threads
Servlet, JSP, MySQL webb app
dynamical page content refreshing
MVC (urgent)
Need some general help regarding MVC design.
Database connection shouldnt be in Servlet?