Invalid cast type error

G

Glenn Robinson

Hello,

I create a new class object at runtime using:

Class dmClass = Class.forName(dmClassName);

I want to be able to use the Class object, dmClass, to cast new objects but
I can't seem to get this to work. I've tried:

(dmClass) .......
(dmClass.getName()).....

But I get an Invalid Cast type expression error.

How can I use dmClass as the cast type in a statement?

Thanks
 
A

Andrew Thompson

Hello,

I create a new class object at runtime using:
Class dmClass = Class.forName(dmClassName);

Try..
Object o = dmClass.newInstance();

And please do not cross-post betweenn c.l.j.programmer
amd c.l.j.help. Perhaps stick tp c.l.j.help on this one.

F'Ups set to c.l.j.help.

HTH
 
M

Michael Borgwardt

Glenn said:
I create a new class object at runtime using:

Class dmClass = Class.forName(dmClassName); []
How can I use dmClass as the cast type in a statement?

You cannot, that's impossible.

What are you trying to achieve with it anyway?
 
G

Glenn Robinson

Michael said:
Glenn said:
I create a new class object at runtime using:

Class dmClass = Class.forName(dmClassName); []
How can I use dmClass as the cast type in a statement?

You cannot, that's impossible.

What are you trying to achieve with it anyway?

I have:
interface DataManager
class SasDMImp which implements DataManager

I do the following:

String dmClassName = "SasDMImp";
Class dmClass = Class.forName(dmClassName);

I now want to use the SasDMImp class to cast a new object and this is the
part I'm having trouble with.

If I hard code the class name I use:

SasDMImp dm = (SasDMImp) Naming.lookup("rmi://" +host + registry);

I want to replace the hard coded SasDMImp with dmClass but I get the Invalid
Cast type when I do this.

Hope this helps.
 
J

Joona I Palaste

Glenn Robinson <[email protected]> scribbled the following
Michael Borgwardt wrote:
Glenn said:
I create a new class object at runtime using:

Class dmClass = Class.forName(dmClassName); []
How can I use dmClass as the cast type in a statement?

You cannot, that's impossible.

What are you trying to achieve with it anyway?
I have:
interface DataManager
class SasDMImp which implements DataManager
I do the following:
String dmClassName = "SasDMImp";
Class dmClass = Class.forName(dmClassName);
I now want to use the SasDMImp class to cast a new object and this is the
part I'm having trouble with.
If I hard code the class name I use:
SasDMImp dm = (SasDMImp) Naming.lookup("rmi://" +host + registry);
I want to replace the hard coded SasDMImp with dmClass but I get the Invalid
Cast type when I do this.
Hope this helps.

This is a well-known situation. Our application uses this form of code
about a hundred times.
My answer to your problem is: Forget about casting to SasDMImp. Cast to
DataManager instead, as it's a known interface, and code that uses your
data manager shouldn't have to care about whether you have a SadDMImp or
some other implementation. If it does, you have a design problem.
 
C

cutthecrap

I don't really get the problem.

Since the target variable has to be statically defined:

ClassA instA;

The cast can be statically defined also:

ClassA instA = (ClassA) someVar;

Class casting is a static compile time activity.
 
J

Joona I Palaste

cutthecrap said:
I don't really get the problem.
Since the target variable has to be statically defined:
ClassA instA;
The cast can be statically defined also:
ClassA instA = (ClassA) someVar;
Class casting is a static compile time activity.

The problem is that the class which is to be instantiated can *not* be
statically defined. That's the whole point of using the
Class.forName() and newInstance() calls. Otherwise you could just
write:
SapDMImp imp = new SapDMImp();
without using Class.forName() or newInstance() at all. But then you'd
be stuck with them SapDMImp class and could not change to another
DataManager implemenation, which is presumably what the OP wants to do.
This is known as the factory pattern. Look it up and you will
understand.
 
C

cutthecrap

Yep, I get that bit, the advanced idea of a "Factory" pattern is not beyond
my 20 years Object Oriented experience.

String clssName = "SasDMImp";
Naming.set("rmi:" + host + reg, Class.forName(clssName).newInstance());

All fine and dandy.

But you were asking about object casting, not object creation?

You wanted to dynamically cast something like

SomeClass obj = (clssName) Naming.lookup("rmi/" + host + reg);

MY POINT is that in that line you no longer need be concerned with the
dynamic class name, since you ALREADY KNOW what you need to cast to, so
just do it:

SomeClass obj = (SomeClass) ... blah blah
 
J

Joona I Palaste

cutthecrap said:
Yep, I get that bit, the advanced idea of a "Factory" pattern is not beyond
my 20 years Object Oriented experience.
String clssName = "SasDMImp";
Naming.set("rmi:" + host + reg, Class.forName(clssName).newInstance());
All fine and dandy.
But you were asking about object casting, not object creation?
You wanted to dynamically cast something like
SomeClass obj = (clssName) Naming.lookup("rmi/" + host + reg);
MY POINT is that in that line you no longer need be concerned with the
dynamic class name, since you ALREADY KNOW what you need to cast to, so
just do it:
SomeClass obj = (SomeClass) ... blah blah

I'm afraid you don't understand. From the OP's earlier message:

====================================================================
From (e-mail address removed) Thu Aug 26 20:13:04 2004
From: Glenn Robinson <[email protected]>
Subject: Re: Invalid cast type error
Newsgroups: comp.lang.java.help,comp.lang.java.programmer
Followup-To: comp.lang.java.help
Date: Thu, 26 Aug 2004 10:14:57 +0100

(snip)

I have:
interface DataManager
class SasDMImp which implements DataManager

I do the following:

String dmClassName = "SasDMImp";
Class dmClass = Class.forName(dmClassName);

I now want to use the SasDMImp class to cast a new object and this is the
part I'm having trouble with.

If I hard code the class name I use:

SasDMImp dm = (SasDMImp) Naming.lookup("rmi://" +host + registry);

I want to replace the hard coded SasDMImp with dmClass but I get the Invalid
Cast type when I do this.
=========================================================================

Note the last paragraph: "I want to replace the hard coded SasDMImp with
dmClass". This is a very strong implication that he wants a situation
where you DO NOT necessarily already know which clas to cast to.
Otherwise he would be just fine using hardcoded classnames and not
bothering us about it. He already knows how to do so - he said it
above.
In Java, you CAN NOT cast anything to a type which you do not already
know. Variable types must be known at compile time. There is no way
around this.
Fortunately, in the OP's case, he can very well use the DataManager
interface to cast the object to, like I suggested. That would be, hey,
I don't know, THE WHOLE POINT OF THE INTERFACE, and stuff.
 
C

cutthecrap

Talk about leading a horse to water....

Did you not really read my note?

I agree that he does not really have a problem. I agree that that is the
point of having an Interface or common base class.

My point is that in order for there to be a requirement to make a cast,
there must already be a *statically* declared destination variable to
which the assignment must be made.

Therefore, there can *never* be a requirement for a dynamic cast.

Please read those previous two sentences carefully before
commenting further.

As you said clearly "you CAN NOT cast anything to a type you do not
already know".

Isn't this a little bit similar to my statement "since you ALREADY KNOW
what you need to cast to". We are both saying the same thing.

Bloody hell this is hard work, what chance is there of discussing anything
remotely complicated!
 
M

Michael Borgwardt

cutthecrap said:
My point is that in order for there to be a requirement to make a cast,
there must already be a *statically* declared destination variable to
which the assignment must be made.

Therefore, there can *never* be a requirement for a dynamic cast.

Not quite true. A dynamic cast could be useful to choose between
overloaded methods - if those were not statically bound, that is.
 
J

Joona I Palaste

cutthecrap said:
Talk about leading a horse to water....
Did you not really read my note?
I agree that he does not really have a problem. I agree that that is the
point of having an Interface or common base class.

I agree with this.
My point is that in order for there to be a requirement to make a cast,
there must already be a *statically* declared destination variable to
which the assignment must be made.

I agree with this too.
Therefore, there can *never* be a requirement for a dynamic cast.
Please read those previous two sentences carefully before
commenting further.
As you said clearly "you CAN NOT cast anything to a type you do not
already know".
Isn't this a little bit similar to my statement "since you ALREADY KNOW
what you need to cast to". We are both saying the same thing.

So we both need to answer to the OP's question with this answer:
"You can not cast your object to a dynamic type. However, you do not
need to. Just cast it to the interface type."
This should be what we've both been trying to say, right?
Bloody hell this is hard work, what chance is there of discussing anything
remotely complicated!

I guess I misunderstood what you were talking about. I thought you were
trying to discuss a case where the implementation class (SasDMImp in
this case) is known in advance, when it's clear from the OP's and my
messages that it isn't. As far as I understand from your recent
message, you are also talking about the case where the implementation
class is not necessarily known in advance.

If we both can agree to "just cast it into the interface type and
forget all about dynamic casting, because Java doesn't support it",
then we're agreed and it's up to the OP to use our solution.

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"The day Microsoft makes something that doesn't suck is probably the day they
start making vacuum cleaners."
- Ernst Jan Plugge
 
T

Tor Iver Wilhelmsen

Michael Borgwardt said:
Not quite true. A dynamic cast could be useful to choose between
overloaded methods - if those were not statically bound, that is.

No, that's what interface types are for; You cast to a common
interface the two classes share.
 
M

Michael Borgwardt

Tor said:
No, that's what interface types are for; You cast to a common
interface the two classes share.

That's not what I was talking about. I meant that dynamic cast could
be used on the parameters of an *overloaded* (not overridden)
method to choose the correct method, i.e.

public void method(Integer i)
{
}
public void method(String s)
{
}

If dynamic casting were possible and overloaded methods
not bound statically, you could do

Object o = returnSomethingThatMightBeAStringOrAnInteger();
method((o.getClass)o);

to automatically call the appropriate method.
 
J

Joona I Palaste

That's not what I was talking about. I meant that dynamic cast could
be used on the parameters of an *overloaded* (not overridden)
method to choose the correct method, i.e.
public void method(Integer i)
{
}
public void method(String s)
{
}
If dynamic casting were possible and overloaded methods
not bound statically, you could do
Object o = returnSomethingThatMightBeAStringOrAnInteger();
method((o.getClass)o);
to automatically call the appropriate method.

And what if o.getClass() happens to be neither Integer nor String, nor
any subclass or either (ignoring the fact that they are final classes
for the sake of argument)? Do you get a ClassCastException or a
NoSuchMethodError?
 
M

Michael Borgwardt

Joona said:
And what if o.getClass() happens to be neither Integer nor String, nor
any subclass or either (ignoring the fact that they are final classes
for the sake of argument)? Do you get a ClassCastException or a
NoSuchMethodError?

Well, it's a hypothetical possibility anyway and probably also. But it's
an example (the only one, I think) where a dynamic cast could have an
effect.
 
J

Joona I Palaste

Well, it's a hypothetical possibility anyway and probably also. But it's
an example (the only one, I think) where a dynamic cast could have an
effect.

I'm having difficulty parsing your first sentence. Probably also what?
 
M

Michael Borgwardt

Joona said:
I'm having difficulty parsing your first sentence. Probably also what?

Oops, forgot to complete it after correcting a typo.

Probably also problematic in other ways, once you consider how to implement it.
 
C

cutthecrap

hmm.. that is actually quite interesting.

Similar to Common Lisp Generic function (I think)

You can clearly arrange a protocol to achieve a co-operative effect, but
that isn't ideal for the example you've given.

You could write a dynamic invoke using the reflexion API - this is what
Jython has to do and isn't so hard:

dyninvoke(target, "methodName", args);

But apart from such scripting environments I would normally go for a
co-operative protocol, something like:

interface dispatcher {
public Object doItToMe(ActionObject action);
}
Then the implementation objects would implement dispatcher, and when they
needed to be processed by the ActionObject it would call:

((dispatcher).doItToMe(this);

with
class DispatcherImpl1 implements dispatcher {
public Object doItToMe(ActionObject action);
action.doIt(this);
}
}

where the "doIt" method can now select on the type of DIspatcherImpl1.

I have used this pattern several times in async message passing systems.
 
F

fg

public void method(Integer i)
{
}
public void method(String s)
{
}

If dynamic casting were possible and overloaded methods
not bound statically, you could do

Object o = returnSomethingThatMightBeAStringOrAnInteger();
method((o.getClass)o);

to automatically call the appropriate method.

In fact you can...
By creating a third method :
public void method(Object o)
{
if (o instanceof Integer)
{
method((Integer)o);
}
else if (o instanceof String)
{
method((String)o);
}
else
{
System.err.println("Error, 'o' is not an Integer nor a String...");
}
}

The point is that if you create a new method
public void method (Long l)
{
}

you must change the method(Object o) to add this possibility.

so if you really want to go over this problem, you can write :

public void method(Object o)
{
Class c = o.getClass();
try
{
Method meth = this.getClass.getDeclaredMethod("method", new Class[]{c});
}
catch (NoSuchMethodException e)
{
System.err.println("Error, 'o' is not a supported Object... Its class is
: " + o.getClass());
e.printStackTrace();
return;
}

meth.invoke(this, new Object[]{o});
}

this code assumes that the methods "method" are inner methods of the current
object ("this", as it is referenced to get the Method object, and to invoke
it).



The pleasure is mine.

Frédéric (French, you may have guessed...)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top