Autocasting in Java – An approach


I’m just wri­ting some Java code and for the thousand-and-first time the­re is some­thing like

public void someMethod(AnyType a) {
 if (a instanceof DerivateOfAnyType) {
  DerivateOfAnyType d=(DerivateOfAnyType)a;
  d.someMethodOfDerivate();
 }
}

Even though the­se-days Java has Gene­rics, Anno­ta­ti­ons and that other cool stuff, you still have need for such casts, and I’m pret­ty sure that if you replace „Any­Ty­pe” with „Object”, you’ll find such occur­ren­ces also in your code (if you are a Java programmer).

Every time I wri­te such stuff, I think for mys­elf: „Why does that Java com­pi­ler not per­form the cast on its own?” I mean: After suc­cess of an „ins­tance­of” check, I can be sure that the object is an ins­tance of the type in ques­ti­on. Why do I have to expli­cit­ly name that again. The code would beco­me much more rea­da­ble and not more con­fu­sing if it were chan­ged into


public void someMethod(AnyType a) {
 if (a instanceof DerivateOfAnyType) {
  a.someMethodOfDerivate(); // ((DerivateOfAnyType)a).someMethodOfDerivate();
 }
}

Sear­ching with goog­le quick­ly lead me to blog ent­ry of Ste­phen Cole­bourne who had pre­cis­e­ly this idea more than five years ago. The dis­cus­sion in the comm­ents of that artic­le show­ed two problems:

  1. It can be ambi­guous to call the auto-deri­va­ted class by its old name („a” in the exam­p­le). The pro­po­sed solu­ti­on was to defi­ne an expli­cit new name within the ins­tance­of statement:

    public void someMethod(AnyType a) {
     if (a instanceof DerivateOfAnyType as d) {
      d.someMethodOfDerivate();
     }
    }
  2. Even using this syn­tax, the­re is more space for ambi­gui­ties. Examp­les were
    boolean b=(a instanceof DerivateType as d);
    or
    if (a instanceof Type1 as t1 || a instanceof Type2 as t2).
    For this pro­blem, the dis­cus­sion ended inconclusively.

After having read that, I’ve ela­bo­ra­ted that auto-cas­ting stuff a bit. The examp­les from abo­ve are a bit patho­lo­gic. Nor­mal­ly, the who­le ins­tance­of stuff is only for one type and only within an if-con­s­truct. So, it all comes down to a syn­tac­tic-sugar thing pre­ven­ting the only sen­si­ble cast from being writ­ten down expli­cit­ly. Which brought me to this rule set:

  • The „ins­tance­of” ope­ra­tor is exten­ded by an (optio­nal) „as” part. So, it is legal to wri­te a instanceof TypeB as b.
  • An ins­tance­of ope­ra­tor exten­ded this way crea­tes a new name „b” for the object ins­tance refe­ren­ced by „a” which refe­ren­ces the same ins­tance auto­ma­gi­cal­ly as being of class „Typ­eB”
  • The new name „b” is only available within the block bound to the state­ment with the exten­ded ins­tance­of declaration.
  • The exten­ded ins­tance­of syn­tax is only allo­wed within a con­junc­ti­ve non-nega­ting logi­cal expression.
  • Fur­ther­mo­re, it is only allo­wed if it is the only „ins­tance­of” state­ment within the logi­cal expression.

The­se defi­ni­ti­ons would make the auto-cas­ting unam­bi­gious by rest­ric­ting it to the actu­al nee­ded case. Things like „if (a!=null && a instanceof B as b)” or „while (a instanceof B as b)” would still be pos­si­ble while „if (!(a instanceof B as b))” or „if (a instanceof B as b || a instanceof C as c)” would not. To me, it seems as if this defi­ni­ti­on of an exten­ded ins­tance­of ope­ra­tor would sol­ve the annoy­ing cas­ting syn­tax of the­se-days Java in this case while avo­i­ding all the patho­lo­gi­cal cases descri­bed in the blog artic­le and its dis­cus­sion men­tio­ned abo­ve. Futher­mo­re, note that all the usu­al rules for cas­ting and assin­ging new con­tent to varia­ble names still app­ly. So, when wri­ting some­thing like „a=new TypeA()”, it would crea­te a new object and lea­ve „b” poin­ting to the old object. In the same way, b=new TypeB() would crea­te a new object just as it would if „b” was declared in the­se-days Java with the expli­cit cast at the begin­ning of the „if” block.

Of cour­se, all of this only is true if I do not miss some­thing in my con­clu­si­ons. But if this works out, I think it would be a nice litt­le exten­si­on to the Java syn­tax which era­diac­tes a rather cum­ber­so­me short­co­ming in the syn­tax. And, of cour­se, it is all com­pi­ler-only. Anyo­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