W3docs

Conversões de String em Java

Converta entre strings e primitivos em Java — Integer.parseInt, Double.parseDouble, String.valueOf e muito mais.

A maioria dos dados chega como texto e a maioria dos dados sai como texto. Entre esses dois limites, eles geralmente vivem na forma de algo mais útil — um int, um double, um boolean, um LocalDate. Este capítulo trata das duas direções de conversão entre String e os tipos primitivos, os tipos wrapper e os arrays de caracteres.

Há um pequeno vocabulário que vale a pena memorizar; uma vez que você o conheça, a resposta para "como transformo esta string em um X" é uma linha de código em qualquer situação.

String → primitivo: a família parse...

Cada classe wrapper possui um método estático que recebe uma String e retorna o primitivo correspondente:

int    i = Integer.parseInt("42");
long   l = Long.parseLong("9999999999");
double d = Double.parseDouble("3.14");
float  f = Float.parseFloat("3.14");
short  s = Short.parseShort("32000");
byte   b = Byte.parseByte("127");
boolean ok = Boolean.parseBoolean("true");  // any case-insensitive "true"; everything else → false

Essas são as ferramentas padrão. Elas lançam NumberFormatException para entradas que não fazem parse — incluindo null, strings vazias, strings com espaços, decimais específicos de localidade como "3,14" e valores fora do intervalo.

Integer.parseInt(" 42 ");      // NumberFormatException — trim first
Integer.parseInt("3.0");       // NumberFormatException — that's a double
Integer.parseInt("1234567890123"); // NumberFormatException — overflows int

Integer.parseInt aceita um segundo argumento opcional para a base numérica:

Integer.parseInt("ff", 16);    // 255
Integer.parseInt("1010", 2);   // 10
Integer.parseInt("777", 8);    // 511 — the radix is the second arg, not a prefix
Integer.parseInt("0x1A", 16);  // NumberFormatException — no "0x" prefix; pass just "1A"

parseInt lê os dígitos literais na base que você passa; ele não entende prefixos de código-fonte como 0x ou um 0 inicial para octal. Portanto, Integer.parseInt("0777", 8) funciona bem — o 0 inicial é simplesmente mais um dígito octal — mas Integer.parseInt("0x1A", 16) lança uma exceção, porque x não é um dígito de base 16. Remova qualquer prefixo você mesmo antes de fazer o parse.

Para interpretação sem sinal do bit mais significativo em valores de 32 e 64 bits, o JDK oferece Integer.parseUnsignedInt e Long.parseUnsignedLong.

String → wrapper: valueOf vs parse...

O valueOf estático em cada wrapper faz o mesmo parse, mas retorna o tipo wrapper:

Integer n = Integer.valueOf("42");     // Integer, not int
Double d  = Double.valueOf("3.14");    // Double, not double

Os dois diferem em três pontos que ocasionalmente importam:

  • Tipo de retorno. parseIntint, valueOfInteger. Escolha o que seu destino exige.
  • Cache. Integer.valueOf(int) e Long.valueOf(long) armazenam em cache números pequenos (-128..127 por padrão), retornando a mesma instância de Integer em chamadas repetidas. parseInt retorna um primitivo, então o cache não tem relevância — mas quando você estaria encaixotando o resultado de qualquer forma, valueOf é mais eficiente.
  • Comportamento em overflow. Idêntico — ambos lançam NumberFormatException.

Regra prática: se você quer um primitivo, use parseInt; se você quer um wrapper, use valueOf. Não escreva Integer.valueOf(Integer.parseInt(s)) — isso é código de dois parses para um resultado de um parse.

Primitivo → String: String.valueOf e similares

A direção inversa tem duas ferramentas bem nomeadas:

String s1 = String.valueOf(42);              // "42"
String s2 = String.valueOf(3.14);            // "3.14"
String s3 = String.valueOf(true);            // "true"
String s4 = String.valueOf('a');             // "a"
String s5 = String.valueOf(new char[]{'h','i'}); // "hi"
String s6 = String.valueOf((Object) null);   // "null"  — NOT an NPE

Todo wrapper também possui um toString que recebe o primitivo:

Integer.toString(42);          // "42"
Integer.toString(255, 16);     // "ff"   — radix overload
Long.toString(123456789L);     // "123456789"
Double.toString(3.14);         // "3.14"

E, claro, a concatenação com "" funciona:

String s = "" + 42;            // "42"

String.valueOf é o mais geral e o estilo mais defensável — nunca lança exceção com null e lida com todos os primitivos mais Object. Para formatação numérica onde você precisa de largura, sinal, agrupamento ou decimais com reconhecimento de localidade, use String.format.

Strings e chars

Um char é um primitivo (uma unidade de código UTF-16); uma String é uma sequência deles. Conversões nas duas direções:

String  s   = String.valueOf('a');       // "a"
char    c1  = "abc".charAt(0);           // 'a'
char[]  arr = "abc".toCharArray();       // ['a', 'b', 'c']
String  s2  = new String(arr);           // "abc"
String  s3  = new String(arr, 1, 2);     // "bc" — offset + count

String.toCharArray() sempre retorna um array novo e modificável. Essa é a ferramenta certa quando você precisa modificar caracteres (por exemplo, para limpar um buffer de senha) — a própria String não pode oferecer uma visão mutável.

Strings e bytes

Bytes são o formato de transmissão; strings são a forma em memória. A conversão sempre envolve um charset, e a resposta certa é sempre passá-lo explicitamente:

byte[] bytes = "héllo".getBytes(StandardCharsets.UTF_8);
String back  = new String(bytes, StandardCharsets.UTF_8);

As sobrecargas sem argumentos (getBytes(), new String(bytes)) usam o charset padrão da JVM, que depende da plataforma e é uma fonte constante de bugs do tipo "funciona na minha máquina". Sempre passe um Charset. UTF-8 é o padrão correto para código novo; sistemas legados às vezes precisam de Latin-1 ou uma das páginas de código do Windows.

Conversões que não existem

Algumas conversões que as pessoas buscam e que não estão disponíveis:

  • intchar pelo valor do dígito. (char) 5 é o caractere de controle no ponto de código 5, não '5'. Use Character.forDigit(5, 10) ou (char) ('0' + 5).
  • charint pelo valor do dígito. (int) '5' é 53, não 5. Use Character.digit('5', 10) ou '5' - '0'.
  • String → numérico com valor padrão em caso de falha. Java não possui um parseIntOrDefault. A versão idiomática é um pequeno helper:
static int parseIntOr(String s, int fallback) {
  try { return Integer.parseInt(s); }
  catch (NumberFormatException e) { return fallback; }
}

Conversão não é validação

O maior erro com conversão de string para primitivo é tratar um parse bem-sucedido como uma validação bem-sucedida. Integer.parseInt("0") retorna 0 para qualquer entrada que o usuário digitar como zero, incluindo "0", "00", "+0" e "-0" — todos fazem parse para o mesmo valor. Se você se importa se a entrada era canônica, faça o parse e depois converta de volta:

int v = Integer.parseInt(input);
if (!Integer.toString(v).equals(input)) {
  throw new IllegalArgumentException("non-canonical integer: " + input);
}

Para entradas numéricas de formulários voltados ao usuário, valide o formato primeiro (regex, comprimento, caracteres permitidos), depois faça o parse. Não confie no parser para dizer se a entrada era razoável.

Um exemplo prático

Um programa que converte nas duas direções nos tipos mais comuns, incluindo um helper robusto com valor padrão em caso de falha, uma ida e volta em hex e uma ida e volta de bytes/string com UTF-8.

java— editable, runs on the server

Três detalhes para observar na saída. A string héllo faz a ida e volta pelo UTF-8 sem problemas — cinco caracteres se tornam seis bytes (o é ocupa dois), e os bytes resultantes fazem parse de volta nos mesmos cinco caracteres. O String.valueOf((Object)null) produz "null" em vez de lançar uma exceção — isso é intencional; é por isso que "x = " + nullable não quebra. E o helper parseIntOr lida com entrada inválida, entrada com espaços e entrada null sem que o site de chamada precise saber.

O que vem a seguir

O capítulo que encerra a Parte 9 aborda os dois métodos mais usados de "string entra, lista sai / lista entra, string sai" na biblioteca padrão — e as variantes com regex que ficam por baixo deles. Continue em Java String split() e join().

Prática

Prática
Qual é a diferença entre `Integer.parseInt('42')` e `Integer.valueOf('42')`?
Qual é a diferença entre `Integer.parseInt('42')` e `Integer.valueOf('42')`?
Was this page helpful?