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 pro­grammer).

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­tan­ce­of” check, I can be sure that the object is an ins­tan­ce 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 read­a­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­cise­ly this idea more than five years ago. The dis­cus­sion in the com­ments of that arti­cle show­ed two pro­blems:

  1. It can be ambi­guous to call the auto-deri­va­ted class by its old name („a” in the examp­le). The pro­po­sed solu­ti­on was to defi­ne an expli­cit new name wit­hin the ins­tan­ce­of state­ment:

    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 incon­clu­si­ve­ly.

After having read that, I’ve ela­bo­ra­ted that auto-cas­ting stuff a bit. The examp­les from above are a bit patho­lo­gic. Nor­mal­ly, the who­le ins­tan­ce­of stuff is only for one type and only wit­hin an if-con­struct. 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­tan­ce­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­tan­ce­of ope­ra­tor exten­ded this way crea­tes a new name „b” for the object ins­tan­ce refe­ren­ced by „a” which refe­ren­ces the same ins­tan­ce auto­ma­gi­cal­ly as being of class „TypeB”
  • The new name „b” is only avail­ab­le wit­hin the block bound to the state­ment with the exten­ded ins­tan­ce­of decla­ra­ti­on.
  • The exten­ded ins­tan­ce­of syn­tax is only allo­wed wit­hin a con­junc­tive non-nega­ting logi­cal expres­si­on.
  • Fur­ther­mo­re, it is only allo­wed if it is the only „ins­tan­ce­of” state­ment wit­hin the logi­cal expres­si­on.

The­se defi­ni­ti­ons would make the auto-cas­ting unam­bi­gious by restric­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­tan­ce­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 arti­cle and its dis­cus­sion men­tio­ned above. 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 decla­red 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­m­ing 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.