As you know, Mo, I have also had a tough time figuring out what is *bad*
about passing in obj.getClass().
I can understand if there are methods that you don't want to expose to the
user in the derived class. In your example, if I wanted to prevent C.exit()
from being callable I should pass in B.getClass()... right? (Would
java::cast allow me to cast the object to type C anyway?)
Does the bad stuff happen because non-public methods and fields become
exposed? Is there something *fatal* about it though? Does it cause an
exception somewhere?
That's what I don't understand. In all my usages of
ReflectObject.newInstance() I *want* the most derived class, I do not want
the class that it extends from.
> -----Original Message-----
> From: Mo DeJong [mailto:[EMAIL PROTECTED]]
> Sent: Wednesday, June 28, 2000 8:06 PM
> To: Dr Wes Munsil
> Cc: [EMAIL PROTECTED]
> Subject: [Tcl Java] Re: [Tcl Java] Re: [Tcl Java] Re: [Tcl Java] Small
> test case
>
>
> On Wed, 28 Jun 2000, Dr Wes Munsil wrote:
>
> > Yes, in Java, I need to know the class of an object in a
> vector, so I can cast it back
> > to that class if I need to call any of that class's methods.
> getClass() tells me exactly
> > that. So if that is incorrect in TclBlend, there must be
> something else going on.
>
> That is incorrect. The Class returned by getClass() is not always
> going to be the same as the class you would cast to. You need
> to pass the class you would have done the cast to to newInstance().
>
> > I vaguely see what you're driving at, but this example doesn't call
> > ReflectObject.newInstance() at all, so I'm not clear on how it
> applies to the
> > discussion. If h is set, not by calling a static method that
> does a Java new, but by
> > calling a Tcl extension that does a
> ReflectObject.newInstance(), then I would in fact
> > expect exactly that NEVER_CALL should be accessible via h,
> since the class of h is
> > Hashtable2.
>
> Of course, you would need to subst your own call to some Java
> method for the java::call I put in. The point is that the
> method signature is "Hashtable get()" not "Hashtable2 get()",
> so you should not be able to call the NEVER_CALL() method via h.
>
> > Mo, I'm sure you are frustrated at having to explain this over
> and over again, and I
> > apologize for being dense, but I am just not getting it. I
> think part of the confusion
> > stems from your use of the phrase "its most derived type." The
> only type that is not
> > "derived" from some other (I assume you mean extended) is
> Object, so all the guidance I
> > can deduce from that is to always specify Object in the
> ReflectObject.newInstance()
> > call.
>
> It seems clear that I am not explaining this properly.
> Here is an example inheritance relationship.
>
> Object -> A -> B -> C
>
> If you put an object of type B into a Java Vector, you would
> need to cast it back up to B when you extract it from the
> vector.
>
> Vector v = ...
>
> B b = (B) v.elementAt(0);
>
>
> Now lets say that instead of a B, you put a C into the
> vector. You could extract an object of type C with
> the exact same code because C extends B.
>
> Note that in this scenerio you would never call
> getClass() for anything, you would always need
> to know the types of the Object you are extracting
> from a Vector.
>
> Now lets say that type C defined an exit() method.
> This exit() method would just call System.exit(-1).
>
> class C extends B {
> private C() {}
>
> B getInst() {return new C();}
>
> void exit() {System.exit(-1);}
> }
>
> In regular Java code, you would
> not be able to invoke the C.exit()
> method (unless you called getInst()
> and did a cast up to C, but that
> is another story).
>
>
> Now lets look at the right and wrong
> way to reflect this class.
>
> (Wrong)
>
> Object o = ...
>
> ReflectObject.newInstance(interp, o.getClass, o);
>
> The above code would reflect it as an instance
> of type C. That means you could invoke the
> exit command from inside Tcl with "$o exit".
>
>
> (Right)
>
> Object o = ...
>
> ReflectObject.newInstance(interp, B.class, o);
>
> With this version, the object would be reflected
> as an instance of type B not C. That means the
> method exit() could not be called from the instance.
>
> This is almost exactly the same as:
>
> B b = (B) v.elementAt(0);
>
> The only diff is that you pass B.class to
> ReflectObject.newInstance() instead of
> casting to the given type.
>
>
> Also, you should note that is the type
> you are adding to the reflect table is
> an interface, a call to getClass()
> will not return the interface class
> object, it would return the most
> derived type (like C in the example).
>
> Mo DeJong
> Red Hat Inc
>
> ----------------------------------------------------------------
> The TclJava mailing list is sponsored by Scriptics Corporation.
> To subscribe: send mail to [EMAIL PROTECTED]
> with the word SUBSCRIBE as the subject.
> To unsubscribe: send mail to [EMAIL PROTECTED]
> with the word UNSUBSCRIBE as the subject.
> To send to the list, send email to '[EMAIL PROTECTED]'.
> An archive is available at
> http://www.mail-archive.com/tcljava@scriptics.com
>
----------------------------------------------------------------
The TclJava mailing list is sponsored by Scriptics Corporation.
To subscribe: send mail to [EMAIL PROTECTED]
with the word SUBSCRIBE as the subject.
To unsubscribe: send mail to [EMAIL PROTECTED]
with the word UNSUBSCRIBE as the subject.
To send to the list, send email to '[EMAIL PROTECTED]'.
An archive is available at http://www.mail-archive.com/tcljava@scriptics.com