: code tutorial (v3)

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" ) );