> On Apr 29, 2020, at 12:59 PM, Guy Steele <guy.ste...@oracle.com> wrote: > > > >> On Apr 29, 2020, at 2:47 PM, Dan Smith <daniel.sm...@oracle.com> wrote: >> >> >> >>> On Apr 29, 2020, at 12:35 PM, Guy Steele <guy.ste...@oracle.com> wrote: >>> >>> >>> >>>> On Apr 29, 2020, at 2:23 PM, Dan Smith <daniel.sm...@oracle.com> wrote: >>>> >>>> >>>>> On Apr 29, 2020, at 11:28 AM, Guy Steele <guy.ste...@oracle.com> wrote: >>>>> >>>>> Appealing, but it does raise the question of whether, if the programmer >>>>> uses some sneaky trick such as calling super, this can really be enforced >>>>> ar compile time on all cases. If it can (after all), then your proposed >>>>> wording looks good to me. >>>> >>>> The idea would be to rely on the definition of "assign to" in JLS 16. That >>>> uses a heuristic that counts "x =" or "this.x =" (and, in javac, but not >>>> currently specified properly, "(this).x", etc.) >>>> >>>> Stepping back: in general, it's illegal to assign to a final field. >>>> There's one exception: inside a constructor, where the field is DU, using >>>> an assignment that satisfies the heuristic. In any other case, you get an >>>> error. >>>> >>>> So the language has carved out a small hole permitting assignments, and >>>> this rule closes that hole. >>> >>> That's all very good. >>> >>> But I'm worried about cases where you use some escape catch such as calling >>> super or a static method, passing it "this" as an argument if necessary, >>> and arriving at a place where you need to solve the halting problem to >>> decide at compile time whether the forbidden behavior might occur. I >>> haven't swapped all the current rules back into head enough to decide for >>> myself whether this sort of scenario can actually arise. >> >> I'm leaning heavily on "in general, it's illegal to assign to a final field". >> >> If you try to construct your exploit, you will find that when you try to >> assign to the field, you'll get a "can't assign to final field" error. > > I agree, but when is "when you try to assign" detected in this situation? If > the answer is "run time", then we have a counterexample to Gavin's proposed > promise that "It is a COMPILE-TIME error to assign . . ." (emphasis added). > That's all I am worried about: is it truly a compile-time error in ALL cases, > or an error that is detected at compile time in all the "obvious" cases but > must sometimes be detected at run time in obscure cases?
This is all compile-time. The status quo in Java is that to assign to a final field at compile time, you need to do all of the following: - Be in a constructor for the same class - Reference the field using an unqualified name or qualified by 'this' - Use a simple assignment expression (fieldref = expr) - Place the assignment at a point where the field is DU (has not yet been assigned to through any local control flow path) All other references to the field as an lvalue will be compile-time errors.