Record canonical constructor is required to be public
forax at univ-mlv.fr
forax at univ-mlv.fr
Sat Nov 9 16:37:51 UTC 2019
----- Mail original -----
> De: "Tagir Valeev" <amaembo at gmail.com>
> À: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Envoyé: Samedi 9 Novembre 2019 09:59:19
> Objet: Re: Record canonical constructor is required to be public
> Hello!
>
> The enum argument "goes against the rules of constructors in enums
> (use private or package private depending on the kind of enums)" is
> not appealing to me, as enum instances are never created explicitly,
> so nobody actually needs public enum constructors. I also don't agree
> with encapsulation argument. The record is a transparent entity, which
> doesn't need the encapsulation. If you need an encapsulation, you
> don't need a record. I, however, agree that specifying 'public' on a
> local record constructor looks weird. Probably specifying that
> canonical constructor visibility is the same as record visibility
> would be good.
I use enum as an example where the spec takes care to not allow a constructor with an accessibility wider than what its needed.
For encapsulation, i've used the wrong term, it's about the russian dolls way of Java sees accessibility,
if the package is not visible, the class is not visible, likewise if the class is not visible, the constructor is not visible,
so requiring a public constructor on a non visible class is useless.
>
> With best regards,
> Tagir Valeev.
regards,
Rémi
>
> On Sat, Nov 9, 2019 at 8:32 PM Remi Forax <forax at univ-mlv.fr> wrote:
>>
>> I know we already discuss that but i still don't understand why a canonical
>> constructor has to be public.
>>
>> I understand that a canonical constructor is not a simple constructor because it
>> is also used as a kind of default de-constructor, but this doesn't work well
>> with the current rules for constructors in nested classes/enums and if the
>> class is not visible, it's constructor is not visible anyway.
>>
>> As Brian said in its presentation at Devoxx, records can be used to represent
>> local nominal tuples, like
>>
>> public void foo() {
>> record Pair(String name, int value);
>> ...
>> }
>>
>> If one want to add a requireNonNull using a compact constructor, it will be
>> public void foo() {
>> record Pair(String name, int value) {
>> public Pair {
>> Objects.requireNonNull(name);
>> }
>> }
>> ...
>> }
>>
>> having to declare the constructor to be public in that case seems weird.
>>
>> Mandating that the canonical constructor (hence the compact constructor) to be
>> public:
>> - goes against the idea of encapsulation that a constructor like any members
>> should be the least visible
>> - goes against the rules of default constructors (default constructor use the
>> same visibility as their class) [1]
>> - goes against the rules of constructors in enums (use private or package
>> private depending on the kind of enums) [2]
>>
>> So we a set of rules in the JLS that follows the idea that a constructor should
>> not be public by default in nested classes [1] but the rule for a canonical
>> constructor doesn't follow the same idea [3], this should be fixed.
>>
>> In my opinion, the rule for a canonical constructor should be the same as the
>> rule for a default constructor.
>>
>> regards,
>> Rémi
>>
>>
>> [1] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.8.9
>> [2] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.9.2
>> [3]
> > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.4
More information about the amber-spec-experts
mailing list