Alright, I'll document the current behavior.

On Tue, Aug 19, 2025 at 1:43 AM Kevin Rushforth <kevin.rushfo...@oracle.com>
wrote:

> I am not sure it is worth changing the behavior either. It allowing null
> were ambiguous (or harmful), then it might be worth it. As it is, it seems
> better to just document the current behavior.
>
> -- Kevin
>
>
> On 8/18/2025 2:34 PM, John Hendrikx wrote:
>
> I think it may come down to whether rejecting `null` would be helpful for
> users of these constructors to find problems in their code.  I agree that
> the DateTimeStringConverter is not really a chained constructor with a
> clear (and public) master constructor that is documented to allow `null`
> for certain defaults.  It is more a style of programming used throughout FX
> to provide many constructors (Image is also like that) instead of a Builder
> or static factory method.
>
> I could make arguments that it would make programmatic use easier, but
> that never stopped me from rejecting nulls in my own code.  Callers then
> should just pick their own defaults, like:
>
>        new DateTimeConverter(locale == null ? Locale.DEFAULT : locale,
> pattern == null ? "ddMMyy" : pattern)
>
> Personally, I think this is not worth changing, but I do think it should
> be documented.  Rejecting nulls now will definitely require a CSR and is
> not backwards compatible :/
>
> --John
>
> On 18/08/2025 22:41, Nir Lisker wrote:
>
> But I think I see what you mean better now, for example, there is (Locale
>> locale, String pattern) and (String pattern). If you intending to pass
>> `null` as Locale, why not just use the pattern-only constructor?  I think
>> that still could make sense,
>
>
> OK, but what about `pattern` being null in either?
>
> On Mon, Aug 18, 2025 at 11:30 PM John Hendrikx <john.hendr...@gmail.com>
> wrote:
>
>> If certain patterns make no sense, then I think the master constructor
>> should reject them (if there is one, or perhaps one should be created as a
>> private one).
>>
>> For example, if there is a width/height constructor, but I only specify
>> width and not height, then I think its fine to reject (null, height) and
>> (width, null) while accepting (null, null) and (width, height).
>>
>> But I think I see what you mean better now, for example, there is (Locale
>> locale, String pattern) and (String pattern). If you intending to pass
>> `null` as Locale, why not just use the pattern-only constructor?  I think
>> that still could make sense, especially locale is say coming from a
>> configuration file or some such.  If the constructor `null` here, then it
>> makes it easier to use it programmatically (ie. if my configuration has a
>> Locale then I pass that, if it is null, I pass that -- compare that to
>> having to check for Locale being null and then having to select the correct
>> constructor...
>>
>> --John
>>
>> On 18/08/2025 21:00, Nir Lisker wrote:
>>
>> Aren't these constructors chained?
>>
>>
>> Not all of them. There are 3 tangential creation paths for
>> DateTimeStringConverter and subclasses:
>> 1. Through dateStyle/timeStyle ints with an optional locale that creates
>> the DateFormat with `DateFormat.getDateTimeInstance(dateStyle, timeStyle,
>> locale)` (similar for subclasses). There are 4 constructors here for the
>> combinations of: none, only style(s), only locale, all.
>> 2. Through a String pattern with an optional locale that creates the
>> DateFormat with `new SimpleDateFormat(pattern, locale)`. If pattern is
>> null, it uses path 1 above with default styles and the optional locale. If
>> you wanted to use a pattern to create this converter, passing null makes
>> little sense. It could be surprising to get a "defaults" converter when you
>> intended to customize the format with your own pattern to begin with. I
>> imagine that if you couldn't get a pattern, you'd use your own int styles
>> as a replacement.
>> 3. Through a DateFormat that is used directly. If it's null, it checks if
>> the pattern is null (which it will always be), in which case it uses the
>> defaults of path 1 again (with the default locale since it's not optional
>> here). I find it odd here too to pass null and rely on the
>> "defaults" converter.
>>
>> NumberStringConverter and its subclasses are similar. They have path 2
>> with 4 combinations: none, only pattern, and locale, and both. And they
>> also have path 3 that falls on the default if null.
>>
>> On Mon, Aug 18, 2025 at 9:06 PM John Hendrikx <john.hendr...@gmail.com>
>> wrote:
>>
>>> Aren't these constructors chained?  I believe it is quite common
>>> practice to use nulls when calling a chained constructor to get a default
>>> for that parameter.  If a certain type of convenience constructor is
>>> missing, a caller can pass in `null` for the parameter they'd like
>>> defaulted.  It's not too far-fetched to allow this **if** there is a
>>> constructor where this parameter is omitted and is assigned a default.
>>>
>>> If anything, the constructors IMHO should document that for certain
>>> parameters passing in `null` results in a specific default.
>>>
>>> --John
>>> On 18/08/2025 19:46, Nir Lisker wrote:
>>>
>>> Hi all,
>>>
>>> In DateTimeStringConverter, NumberStringConverter, and their subclasses,
>>> null parameters sent to the constructors are internally converted to
>>> default values. This is not specified, but it's how the implementation
>>> behaves. I'm working on some changes there and was thinking about changing
>>> the behavior to throw NPEs as it makes no sense to pass null into these and
>>> it's probably a bug more than anything.
>>>
>>> The LocalDate/Time converters specified the null-friendly behavior in
>>> their docs even though it doesn't make much sense there either.
>>>
>>> Are we allowed to change this?
>>>
>>> - Nir
>>>
>>>
>

Reply via email to