W3docs

Tipos de Dados em Java

Explore os tipos de dados primitivos do Java (byte, short, int, long, float, double, char, boolean) e os tipos de referência.

Java é estaticamente tipado — toda variável tem um tipo conhecido em tempo de compilação. Os tipos se dividem em duas famílias: primitivos (valores brutos incorporados à linguagem) e tipos de referência (objetos, arrays e tudo o que é criado com new). Este capítulo percorre os dois.

Os oito tipos primitivos

Os primitivos são os únicos valores em Java que não são objetos. Eles armazenam seu valor diretamente no espaço de armazenamento da variável. Java define exatamente oito:

TipoTamanhoIntervaloPadrãoExemplo de literal
byte8 bits-128 a 1270byte b = 100;
short16 bits-32.768 a 32.7670short s = 30000;
int32 bits-2³¹ a 2³¹-1 (≈ ±2,1 bilhões)0int i = 1_000_000;
long64 bits-2⁶³ a 2⁶³-10Llong l = 9_000L;
float32 bitsprecisão simples IEEE 7540.0ffloat f = 3.14f;
double64 bitsprecisão dupla IEEE 7540.0double d = 3.14;
char16 bitsUnidade de código Unicode (U+0000 a U+FFFF)\0char c = 'A';
booleandefinido pela JVMtrue ou falsefalseboolean b = true;

Algumas coisas que valem a pena memorizar:

  • int é o tipo inteiro padrão. A maioria dos contadores e índices são int. Use long somente quando precisar de números acima de ~2 bilhões.
  • double é o tipo de ponto flutuante padrão. O simples 3.14 é um double; 3.14f é um float. Use double a menos que a pressão de memória force o uso de float.
  • Underscores em literais numéricos melhoram a legibilidade: 1_000_000 é o mesmo que 1000000.
  • Valores padrão se aplicam apenas a campos, não a variáveis locais. Uma variável local não tem padrão — você deve inicializá-la antes de lê-la.

Tipos de referência

Todo o resto — String, arrays, suas próprias classes, classes de biblioteca — é um tipo de referência. Uma variável de tipo de referência não contém o objeto em si; ela contém uma referência (essencialmente um ponteiro) para o objeto na heap:

String name = "Ada";
int[] scores = new int[10];
LocalDate today = LocalDate.now();

O valor padrão de qualquer variável de referência é null — um valor especial que significa "nenhum objeto."

String s = null;
System.out.println(s.length());  // throws NullPointerException at runtime

null é a origem de um dos erros de tempo de execução mais comuns em Java. O capítulo Java Exceptions cobre como lidar com a NullPointerException que isso provoca.

Classes wrapper

Cada primitivo tem uma classe wrapper correspondente — um objeto real que envolve o valor primitivo:

PrimitivoWrapper
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

Você precisa de wrappers quando quer colocar primitivos em coleções (que só armazenam objetos):

List<Integer> scores = new ArrayList<>();
scores.add(42);   // autoboxed from int → Integer
int first = scores.get(0);  // unboxed from Integer → int

Java converte automaticamente entre primitivos e wrappers — chamado de autoboxing e unboxing — então na maioria das vezes você não percebe.

Uma nota sobre String

String é um tipo de referência, não um primitivo. É especial o suficiente para que a linguagem lhe conceda uma sintaxe literal ("texto") e o operador +. Strings são imutáveis — uma vez criadas, seu conteúdo nunca muda. Cada "modificação" retorna uma nova string. O capítulo Java Strings aprofunda o tema.

Escolhendo um tipo

Uma pequena árvore de decisão para o Java do dia a dia:

  • Contar coisas ou índices de arraysint
  • Contagens grandes (tamanhos de arquivo, timestamps em milissegundos)long
  • DinheiroBigDecimal (não double — o arredondamento de ponto flutuante vai te pegar)
  • Caractere únicochar
  • Sim/Nãoboolean
  • TextoString
  • Uma data ou hora → tipos em java.time (LocalDate, Instant, Duration)

Resista ao impulso de "economizar memória" usando byte ou short para inteiros comuns. As JVMs são otimizadas para operações com int; short na verdade não usa menos memória na maioria dos casos.

Armadilhas comuns

Alguns comportamentos de tipo surpreendem iniciantes com frequência. Conhecê-los de antemão poupa horas de depuração.

Overflow de inteiros envolve silenciosamente

A aritmética inteira em Java nunca lança exceção em caso de overflow — ela faz wrap-around. Adicionar 1 ao maior int produz o menor int:

int max = Integer.MAX_VALUE;   // 2147483647
System.out.println(max + 1);   // -2147483648

Se um valor puder exceder ~2,1 bilhões, use long. Para contagens que possam ultrapassar até mesmo long, recorra a BigInteger.

Ponto flutuante não é exato

float e double seguem o padrão IEEE 754, que não pode representar a maioria das frações decimais com exatidão. O exemplo clássico:

System.out.println(0.1 + 0.2);   // 0.30000000000000004

É por isso que você nunca deve usar double para dinheiro. Use BigDecimal (construído a partir de uma String, por exemplo, new BigDecimal("0.1")) quando valores decimais exatos importarem.

char é um número

Um char é um inteiro de 16 bits sem sinal que contém uma unidade de código Unicode, portanto participa de operações aritméticas:

char a = 'A';
System.out.println((int) a);   // 65
System.out.println((char) (a + 1));  // B

Compare wrappers com .equals(), não com ==

== em objetos wrapper compara referências, não valores. Por causa de um cache de autoboxing para valores pequenos de Integer (-128 a 127), == parece funcionar para números pequenos e depois falha para números grandes:

Integer a = 127, b = 127;
System.out.println(a == b);   // true  (cached)
Integer c = 128, d = 128;
System.out.println(c == d);   // false (different objects)
System.out.println(c.equals(d));  // true  (compares values)

Sempre use .equals() para comparar valores de wrapper. Veja Java Type Casting para as regras de conversão entre esses tipos.

Uma demonstração funcionando

java— editable, runs on the server

O que vem a seguir

Java Type Casting mostra como converter entre tipos numéricos e entre tipos de referência relacionados.

Prática

Prática
Quais afirmações sobre os tipos de dados em Java estão corretas?
Quais afirmações sobre os tipos de dados em Java estão corretas?
Was this page helpful?