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


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

pu­blic vo­id someMethod(AnyType a) {
 if (a in­stan­ce­of De­ri­va­teO­fAny­Ty­pe) {
  De­ri­va­teO­fAny­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 ha­ve need for su­ch casts, and I’m pret­ty su­re that if you re­pla­ce „Any­Ty­pe“ wi­th „Ob­ject“, you’ll find su­ch oc­cur­ren­ces al­so in your code (if you are a Ja­va pro­gram­mer).

Every ti­me I wri­te su­ch stuff, I think for myself: „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­stan­ce­of“ check, I can be su­re that the ob­ject is an in­stan­ce of the ty­pe in ques­ti­on. Why do I ha­ve to ex­pli­cit­ly na­me that again. The code would be­co­me much mo­re re­a­da­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­stan­ce­of De­ri­va­teO­fAny­Ty­pe) {
  a.someMethodOfDerivate(); // ((DerivateOfAnyType)a).someMethodOfDerivate();
 }
}

Se­ar­ching wi­th goo­gle quick­ly lead me to blog ent­ry of Ste­phen Cole­bour­ne 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 ex­am­ple). 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­stan­ce­of state­ment:

    pu­blic vo­id someMethod(AnyType a) {
     if (a in­stan­ce­of De­ri­va­teO­fAny­Ty­pe as d) {
      d.someMethodOfDerivate();
     }
    }
  2. Even using this syn­tax, the­re is mo­re space for am­bi­gui­ties. Ex­amp­les we­re
    boo­le­an b=(a in­stan­ce­of De­ri­va­te­Ty­pe as d);
    or
    if (a in­stan­ce­of Ty­pe1 as t1 || a in­stan­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 re­ad that, I’ve ela­bo­ra­ted that au­to-cas­ting stuff a bit. The ex­amp­les from above are a bit pa­tho­lo­gic. Nor­mal­ly, the who­le in­stan­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 preven­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­stan­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­stan­ce­of Ty­peB as b.
  • An in­stan­ce­of ope­ra­tor ex­ten­ded this way crea­tes a new na­me „b“ for the ob­ject in­stan­ce re­fe­ren­ced by „a“ which re­fe­ren­ces the sa­me in­stan­ce au­to­ma­gi­cal­ly as being of class „Ty­peB“
  • The new na­me „b“ is on­ly avail­able wi­t­hin the blo­ck bound to the state­ment wi­th the ex­ten­ded in­stan­ce­of de­cla­ra­ti­on.
  • The ex­ten­ded in­stan­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­stan­ce­of“ state­ment wi­t­hin the lo­gi­cal ex­pres­si­on.

The­se de­fi­ni­ti­ons would ma­ke the au­to-cas­ting un­am­bi­gious by re­stric­ting it to the ac­tual nee­ded ca­se. Things li­ke „if (a!=null && a in­stan­ce­of B as b)“ or „whi­le (a in­stan­ce­of B as b)“ would still be pos­si­ble whi­le „if (!(a in­stan­ce­of B as b))“ or „if (a in­stan­ce­of B as b || a in­stan­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­stan­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 whi­le avo­iding 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 usual 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 wi­th the ex­pli­cit cast at the be­gin­ning of the „if“ blo­ck.

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 nice litt­le ex­ten­si­on to the Ja­va syn­tax which era­di­ac­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.