O que é Locale? Quando usar? - Blog Cod3r
16/02/2021 72 0
Java é uma linguagem que dá suporte à internacionalização de suas aplicações, oferecendo diversos recursos que facilitam o desenvolvimento de programas cujas interfaces (sejam elas CLIs ou GUIs) se adaptam a cada região.
Para fazer isto, ao ser iniciada, a JVM elege um conjunto de configurações baseadas no sistema em que ela está sendo executada, chamado locale, que define uma linguagem, uma região e quaisquer variações na maneira de exibir e interpretar certos tipos de dados.
Esses parâmetros ficam armazenados em um objeto Locale que possui um Enum Category com duas constantes, DISPLAY e FORMAT, que armazenam códigos de línguas, que são consultadas por métodos de outras classes para determinar o tratamento de alguns tipos de dados. Esses métodos pertencem a objetos sensíveis ao locale.
Podemos descobrir o locale padrão da nossa JVM com o seguinte código:
public class TesteLocale {
System.out.println(Locale.getDefault(Locale.Category.DISPLAY));
System.out.println(Locale.getDefault(Locale.Category.FORMAT));
Como exemplo de um programa que possui objetos sensíveis ao locale, vamos imaginar um programa que calcula o perímetro de uma circunferência e mostra o resultado:
public class ProgramaPerímetro {
try(Scanner entrada = new Scanner(System.in)) {
System.out.print("Digite o raio: ");
RAIO = entrada.nextDouble();
System.out.format("Perímetro = %.2f%n", 2*Math.PI*RAIO);
Nele existem dois objetos sensíveis ao locale: System e Scanner. Os seus métodos, format e nextDouble, respectivamente, consultam a constante FORMAT do Locale afim de determinar a formatação dos números double, que serão exibidos ou recebidos.
Ao iniciar a JVM no meu sistema, ela atribui à constante FORMAT o código pt_BR, fazendo com que os métodos que lidam com números double imprimam e esperem receber números com uma vírgula como separador decimal.
Caso eu digite o valor do raio usando ponto como separador decimal (o separador padrão nos Estados Unidos), o nextDouble disparará uma exceção InputMismatchException, já que ele esperava receber um número com uma vírgula como separador decimal.
Se quisermos que os objetos sensíveis ao locale utilizem outros parâmetros além dos padrões, podemos instanciar um novo objeto locale da seguinte forma:
// criação do novo objeto Locale
final var localeAmericano = new Locale("en", "US");
// nextDouble usará o Locale criado graças ao método useLocale
RAIO = entrada.useLocale(localeAmericano).nextDouble();
No programa acima, o método format continua exibindo os números com uma vírgula como separador decimal, como é padrão no Brasil, porém espera receber um número com o padrão de formatação americano. Isso ocorre graças ao novo objeto Locale, que instanciamos com os argumentos "en" e "US", que formam o código de língua e de região americano, e o método useLocale.
Como alternativa, podemos determinar um novo locale padrão no início do programa:
// criação e definição do novo Locale padrão
Locale.setDefault(localeAmericano);
Dessa forma, todos os métodos de objetos sensíveis ao locale agora formatam os dados de acordo com os padrões americanos.
O mesmo resultado pode ser alcançado usando os argumentos -Duser.language=en -Duser.country=US ao lançar a JVM, que força ela a usar o locale passado como argumento como padrão. Além disso, evita que instanciemos um objeto Locale no corpo do programa.
No Eclipse, podemos fazer acessando a tela em Window>Java>Installed JREs, selecionando a instalação do Java para a qual você quer estabelecer um locale padrão, clicando em Edit…, e pondo os argumentos para o locale desejado no campo Default VM arguments. Como mostra a imagem abaixo:
O objeto Locale faz parte dos recursos que o Java nos disponibiliza para a criação de aplicações localizadas. Entretanto é muito importante ficar atento a qual locale sua JVM está usando como padrão para evitar bugs relacionados a má interpretação de dados.