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

Reply via email to