Lesson 9: Casting Between Proxy Types
Introduction
As hard as we try, there are some usage patterns where we can't completely hide the fact that you are programming in C++ rather than in Java. Type casting is such a case.
Before Java generics entered the picture, it was very common in Java code to have to cast
from Object
to a concrete type, for example because you had retrieved an element
from a collection and collections always returned their elements through the Object
type to be maximally useful.
Generics made most of these casts unnnecessary by allowing you to declare typesafe Collections of your concrete type.
Our proxy classes remain unaware of the generic type information and therefore still require the casts. Let's look at a typical Java snippet and it's corresponding C++ code:
Hashtable<String,String> ht = new Hashtable<>(); ... String value = ht.get( "key" );
Hashtable ht = new Hashtable(); ... // this will NOT compile String value = (String)ht.get( "key" );
The issue is that the polymorphism exists only on the Java side. On the C++ side, the get
method return an actual Object
instance. That Object
happens to maintain
a reference to a Java String
instance, but as far as the C++ compiler is concerned, it is
an Object
and not a String
and you can't simply cast it to String
.
So how can you cast a C++ proxy object from its type to the proxy type that you know it should be?
dyna_cast()
To the Rescue
We provide a special function called dyna_cast()
as part of every proxy type. That
function accepts any proxy object as an argument and returns a new proxy object of its declaring type.
Typesafety is maintained by testing whether the passed object is assignment-compatible. If it is
compatible, the returned proxy instance will contain a reference to the same Java object as the
passed proxy instance.
If it is not compatible, the returned proxy instance will be set to null
. The passed
object remains valid and usable via its own proxy type instance.
Using dyna_cast()
, the above Java snippet could be written like this in C++:
Hashtable ht = new Hashtable(); ... // this WILL compile and work String value = String::dyna_cast( ht.get( "key" ) );