Au­to­cas­ting in Ja­va – An ap­proach


I’m just wri­ting so­me Ja­va code and for the thousand-and-first time the­re is so­me­thing li­ke

pu­blic vo­id someMethod(AnyType a) {
 if (a in­s­tan­ce­of De­ri­va­teOfAny­Ty­pe) {
  De­ri­va­teOfAny­Ty­pe d=(DerivateOfAnyType)a;
  d.someMethodOfDerivate();
 }
}

Even though the­se-days Ja­va has Ge­ne­rics, An­no­ta­ti­ons and that other cool stuff, you still have need for such casts, and I’m pret­ty su­re that if you re­place „Any­Ty­pe“ with „Ob­ject“, you’ll find such oc­cur­ren­ces al­so in your code (if you are a Ja­va pro­grammer).

Every time I wri­te such stuff, I think for mys­elf: „Why does that Ja­va com­pi­ler not per­form the cast on its own?“ I me­an: Af­ter suc­cess of an „in­s­tan­ce­of“ check, I can be su­re that the ob­ject is an in­s­tan­ce of the ty­pe in ques­ti­on. Why do I have to ex­pli­cit­ly na­me that again. The code would be­co­me much mo­re read­a­ble and not mo­re con­fu­sing if it we­re chan­ged in­to


pu­blic vo­id someMethod(AnyType a) {
 if (a in­s­tan­ce­of De­ri­va­teOfAny­Ty­pe) {
  a.someMethodOfDerivate(); // ((DerivateOfAnyType)a).someMethodOfDerivate();
 }
}

Se­ar­ching with goog­le quick­ly lead me to blog ent­ry of Ste­phen Co­le­bourne who had pre­cise­ly this idea mo­re than fi­ve ye­ars ago. The dis­cus­sion in the com­ments of that ar­ti­cle show­ed two pro­blems:

  1. It can be am­bi­guous to call the au­to-de­ri­va­ted class by its old na­me („a“ in the examp­le). The pro­po­sed so­lu­ti­on was to de­fi­ne an ex­pli­cit new na­me wi­t­hin the in­s­tan­ce­of state­ment:

    pu­blic vo­id someMethod(AnyType a) {
     if (a in­s­tan­ce­of De­ri­va­teOfAny­Ty­pe as d) {
      d.someMethodOfDerivate();
     }
    }
  2. Even using this syn­tax, the­re is mo­re space for am­bi­gui­ties. Examp­les we­re
    boole­an b=(a in­s­tan­ce­of De­ri­va­te­Ty­pe as d);
    or
    if (a in­s­tan­ce­of Ty­pe1 as t1 || a in­s­tan­ce­of Ty­pe2 as t2).
    For this pro­blem, the dis­cus­sion en­ded in­con­clu­si­ve­ly.

Af­ter ha­ving read that, I’ve ela­bo­ra­ted that au­to-cas­ting stuff a bit. The examp­les from above are a bit pa­tho­lo­gic. Nor­mal­ly, the who­le in­s­tan­ce­of stuff is on­ly for one ty­pe and on­ly wi­t­hin an if-con­struct. So, it all co­mes down to a syn­tac­tic-su­gar thing pre­ven­ting the on­ly sen­si­ble cast from being writ­ten down ex­pli­cit­ly. Which brought me to this ru­le set:

  • The „in­s­tan­ce­of“ ope­ra­tor is ex­ten­ded by an (op­tio­nal) „as“ part. So, it is le­gal to wri­te a in­s­tan­ce­of Ty­peB as b.
  • An in­s­tan­ce­of ope­ra­tor ex­ten­ded this way crea­tes a new na­me „b“ for the ob­ject in­s­tan­ce re­fe­ren­ced by „a“ which re­fe­ren­ces the sa­me in­s­tan­ce au­to­ma­gi­cal­ly as being of class „Ty­peB“
  • The new na­me „b“ is on­ly avail­ab­le wi­t­hin the block bound to the state­ment with the ex­ten­ded in­s­tan­ce­of de­cla­ra­ti­on.
  • The ex­ten­ded in­s­tan­ce­of syn­tax is on­ly al­lo­wed wi­t­hin a con­junc­tive non-ne­ga­ting lo­gi­cal ex­pres­si­on.
  • Fur­ther­mo­re, it is on­ly al­lo­wed if it is the on­ly „in­s­tan­ce­of“ state­ment wi­t­hin the lo­gi­cal ex­pres­si­on.

The­se de­fi­ni­ti­ons would make the au­to-cas­ting un­am­bi­gious by restric­ting it to the ac­tu­al nee­ded ca­se. Things li­ke „if (a!=null && a in­s­tan­ce­of B as b)“ or „while (a in­s­tan­ce­of B as b)“ would still be pos­si­ble while „if (!(a in­s­tan­ce­of B as b))“ or „if (a in­s­tan­ce­of B as b || a in­s­tan­ce­of C as c)“ would not. To me, it seems as if this de­fi­ni­ti­on of an ex­ten­ded in­s­tan­ce­of ope­ra­tor would sol­ve the an­noy­ing cas­ting syn­tax of the­se-days Ja­va in this ca­se while avo­i­ding all the pa­tho­lo­gi­cal ca­ses de­scri­bed in the blog ar­ti­cle and its dis­cus­sion men­tio­ned above. Fu­ther­mo­re, no­te that all the usu­al ru­les for cas­ting and as­sin­ging new con­tent to va­ria­ble na­mes still ap­p­ly. So, when wri­ting so­me­thing li­ke „a=new Ty­peA()„, it would crea­te a new ob­ject and lea­ve „b“ poin­ting to the old ob­ject. In the sa­me way, b=new Ty­peB() would crea­te a new ob­ject just as it would if „b“ was de­cla­red in the­se-days Ja­va with the ex­pli­cit cast at the be­gin­ning of the „if“ block.

Of cour­se, all of this on­ly is true if I do not miss so­me­thing in my con­clu­si­ons. But if this works out, I think it would be a ni­ce litt­le ex­ten­si­on to the Ja­va syn­tax which era­diac­tes a ra­ther cum­ber­so­me short­co­m­ing in the syn­tax. And, of cour­se, it is all com­pi­ler-on­ly. An­yo­ne kno­wing how to wri­te a JSR?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.