Dúvida básica: Locale.setDefault(new Locale("pt", "BR"));

Colegas,

Tinhamos um site hospedado na locaweb e migramos para uma hospedagem fora do Brasil.
A formatação de valores funfava legal, porém agora antes de declarar um DecimalFormat eu preciso setar o Locale.
A minha pergunta: Existe alguma forma de declarar isso uma única vez na aplicação ou tenho que declarar toda vez, como estou fazendo no código abaixo?

Muito obrigado,

Marques

Locale.setDefault(new Locale("pt", "BR"));
DecimalFormat df = new java.text.DecimalFormat("###,####,##");

Locale.setDefault seta o default locale para a aplicação Java inteirinha, a partir do momento de sua execução. Isso pode ser inconveniente se a aplicação estiver hospedada em um Application Server ou Web Container que é compartilhado por várias aplicações, incluindo algumas que não são suas e que devem ter o locale setado para outras línguas.

De qualquer maneira, o seu exemplo de “DecimalFormat” está ligeiramente esquisito. Ele teria de ser:

DecimalFormat df = new java.text.DecimalFormat("###,####.##");  

Note que o “.” designa o ponto flutuante (que em português é uma vírgula) e o “,” é o separador de milhares (que em português habitualmente é um “.” mas já vi também como um simples espaço.)

Meu caro gurú thingol,

Quanto a esquisitice do DecimalFormat vc tem razão, foi erro de digitação.
Considerando a tua colocação acerca do inconveniente do Locale.setDefault setar também para todas as apicações do web container, como vc faz para setar somente para a sua aplicação?

Muito obrigado,

Marques

[quote=Marques]Meu caro gurú thingol,

Quanto a esquisitice do DecimalFormat vc tem razão, foi erro de digitação.
Considerando a tua colocação acerca do inconveniente do Locale.setDefault setar também para todas as apicações do web container, como vc faz para setar somente para a sua aplicação?

Muito obrigado,

Marques[/quote]

Aqui a gente cria um objeto Locale em algum lugar da inicialização e vai passando como parâmetro pra onde precisa - é melhor que usar o setDefault(). Acredito que o melhor mesmo seria colocar ele em alguma classe de Constantes ou algo assim…

É isso mesmo que o MarceloS disse. A única coisa chata é, por exemplo, criar um DecimalFormat com locale:

DecimalFormatSymbols dfs = new DecimalFormatSymbols (new Locale ("pt", "BR"));
NumberFormat nf = new DecimalFormat ("bla ble bli", dfs);

E outra coisa que acho mais chata ainda é que você não pode supor que um DecimalFormat ou um DateFormat sejam “thread-safe”. Eu já tive problemas com isso, e acabei tendo de criar um ThreadLocal uma vez (o post abaixo é para um DateFormat, mas o DecimalFormat tem problemas semelhantes.)

http://www.guj.com.br/posts/list/38040.java#202482

thingol, não entendi o que você falou sobre o DateFormat não ser thread safe; podes dar uma esclarecida?

Rodei seu teste do outro tópico e não apontou erro nenhum - tanto rodando com a linha

DateFormat df = (DateFormat) tl.get(); // --> método correto

quanto rodando com a linha

DateFormat df = staticDf;               // --> método incorreto

Qual seria a saída esperada?

[quote=MarceloS]thingol, não entendi o que você falou sobre o DateFormat não ser thread safe; podes dar uma esclarecida?

Rodei seu teste do outro tópico e não apontou erro nenhum - tanto rodando com a linha

DateFormat df = (DateFormat) tl.get(); // --> método correto

quanto rodando com a linha

DateFormat df = staticDf;               // --> método incorreto

Qual seria a saída esperada?[/quote]

Então… esses erros de threading são bastante insidiosos*; você precisa rodar um teste repetidas vezes, para que eles apareçam. Normalmente eles aparecem em produção, ou então no ambiente de teste de carga quando você simula múltiplos usuários.

  • Ou seja, são aqueles erros sinistros que parecem ser coisa de Você-sabe-quem. Mas eles são só erros de “threading”; não atribua seus erros a alguma entidade sobrenatural.