Locale.forLanguageTag() vs new Locale()
Asked Answered
E

1

8

Which one to use?

final Locale locale = Locale.forLanguageTag("en-US");

or

final Locale locale = new Locale("en", "US");

Both of them have tons of code when you look at their implementations and I cannot see from this code which one is faster or should be preferred.

As I use it for every single request to my web application, it would be nice to know which one is more suitable for my case.

Enemy answered 7/9, 2022 at 14:42 Comment(6)
For that very specific case using no constructor at all but instead the already existing static final Locale.US would be best. Are the parameters you pass into it variable and you therefor cannot use the existing defined static variable?Lorylose
On the whole I would say it is better to use a factory method when one is provided, because it gives the opportunity to reuse an existing instance rather than creating a new one every time it is invoked (as with new). This is not to say you won't get a new instance with the factory method, just that you don't have to. But, if there is a static member, as mentioned by @OHGODSPIDERS, that's even better again.Lubricous
@OHGODSPIDERS Thanks for your answer. I used en-US just as an example and also am aware of this constant. But I'll be getting different values such as "hr-HR", "hr", "sr-RS" and so, which are not defined in constants.Enemy
Do I remember correctly that forLanguageTag() gives stricter argument validation? If so, use it, validation is invaluable.Underdrawers
So you basically get a single language tag as your input? In that case even without knowing the factory method uses a cache the case should be obvious: don't parse the input yourself but let the well tested forLanguageTag() do its thing.Justify
With Java 21 the constructor taking string arguments - i.e. new Locale() is DEPRECATEDCovington
R
1

Constants

Locale class provides a number of constants for frequently used locales: Locale.CANADA, Locale.CANADA_FRENCH, Locale.CHINA, Locale.UK, etc.

Instead of creating a new instance of locale for English as a language and US as a country via new Locale("en", "US") it's preferable to use static field Locale.US.

Locale constructors

There are three overloaded constructors which allow you to create a Local object from language, country and variant.

If you're enough with this information, go with a constructor.

Note: constructor call always creates a new object in memory.

Locale.forLanguageTag

Static method Locale#forLanguageTag() allows to construct an instance of Locale by providing IETF BCP 47 language tag (also see RFC 4647 "Matching of Language Tags" and RFC 5646 "Tags for Identifying Languages").

Withing a language tag apart from the language and country you can specify various details like calendar, numeric system, currency.

Note: forLanguageTag() (as well as Local.Builder) after parsing is complete, provides an instance from the Cache (if already exists).

Example:

Locale buddhistCal = Locale.forLanguageTag("en-EN-u-ca-buddhist");
Locale arabicNum = Locale.forLanguageTag("en-EN-u-nu-arab");
Locale thaiNum = Locale.forLanguageTag("en-EN-u-nu-thai");
        
LocalDate date = LocalDate.now();
    
System.out.println(date);
System.out.println(date.format(DateTimeFormatter.ISO_DATE.localizedBy(buddhistCal)));
System.out.println(date.format(DateTimeFormatter.ISO_DATE.localizedBy(arabicNum)));
System.out.println(date.format(DateTimeFormatter.ISO_DATE.localizedBy(thaiNum)));

Output:

2022-09-07
2565-09-07     // buddhist calendar
٢٠٢٢-٠٩-٠٧     // arabic numbers
๒๐๒๒-๐๙-๐๗    // thai numbers
Russianize answered 7/9, 2022 at 16:8 Comment(4)
This far I know already. My concern was more about performance and memory footprint than just plain usage. I am aware there is a cache for Locale instances so I guess the same locale won't be created each time again, but rather fetched from cache. But behind the stage there are tons of parsing and other code that I didn't analyze and it would be nice to know which one of both I mentioned does less parsing and other processing. Hope it's clear now what I wanted.Enemy
@horvoje "the same locale won't be created each time again" - a new instance would be created every time a constructor is being used. Conversely, with forLanguageTag() or Locale.Builder you'll get an instance from a Cache. Here's a proof regarding built-in caching of locales: jdoodle.com/ia/uRGRussianize
@horvoje "performance and memory footprint" - so your concern is whether you can rely on the Cache for Locale objects? There are many moving in forLanguageTag() which being galvanized into action before an instance from the Cache can be provided. I guess you are using a limited set of Locales in your application, so you might maintain your own cache.Russianize
Are the equivalents of -u-ca-buddhist, -u-nu-thai, etc also available somehow via the variant parameter of the 3-parameter Locale constructor? It would seem so but I can't see it specifically stated or denied anywhere and my attempts to guess how have all failed.Sacramentalism

© 2022 - 2024 — McMap. All rights reserved.