W3docs

Atributos de Classe Java (Campos)

Declare campos de instância em uma classe Java, defina valores iniciais e acesse-os através de objetos.

Os atributos de uma classe são as variáveis declaradas dentro dela — os dados que cada objeto carrega. A maioria dos autores os chama de campos (como faz a Especificação da Linguagem Java), e "atributo" é o termo mais geral da POO; eles significam a mesma coisa. Este capítulo trata de como declará-los, quais valores eles recebem inicialmente e como lê-los e escrevê-los de fora da classe.

Declarando um campo

Um campo se parece com uma variável local, mas fica no corpo da classe em vez de dentro de um método:

public class Book {
  String title;
  String author;
  int    pages;
  boolean inPrint;
}

Cada instância de Book recebe sua própria cópia desses quatro campos. Dois livros têm duas strings title separadas, dois ints pages separados e assim por diante. Eles vivem enquanto o objeto existir, ou seja, até que nada mais o referencie.

Valores padrão

Se você não inicializar um campo, o Java o inicializa para você. Os valores padrão dependem do tipo:

TipoPadrão
byte, short, int, long0
float, double0.0
char'�' (o caractere nulo, ponto de código 0 — não um espaço)
booleanfalse
qualquer tipo de objetonull
Book b = new Book();
System.out.println(b.title);    // null
System.out.println(b.pages);    // 0
System.out.println(b.inPrint);  // false

Este é um dos principais pontos em que os campos diferem das variáveis locais dentro de métodos — variáveis locais não recebem valor padrão, e o compilador se recusa a deixar você ler uma antes de atribuir um valor a ela. Os campos sempre começam com algum valor.

Inicializadores inline

Você pode dar a um campo um valor logo onde o declara:

public class Book {
  String title   = "Untitled";
  int    pages   = 0;
  boolean inPrint = true;
}

O inicializador é executado uma vez por objeto, quando esse objeto é criado. Ele é executado na ordem de declaração, antes do corpo do construtor. Se um campo precisa de uma configuração mais complexa, esse é o trabalho do construtor.

Lendo e escrevendo campos

Você usa <referência>.<campo> de fora, e apenas <nomeDoCampo> (ou this.<nomeDoCampo>) de dentro da própria classe:

Book b = new Book();
b.title = "Effective Java";    // write
String t = b.title;            // read

Dentro da classe:

public class Book {
  String title;
  void rename(String t) {
    title = t;             // same as this.title = t;
  }
}

O capítulo sobre a palavra-chave this explica quando você precisa do qualificador explícito this. e quando não precisa.

Convenções de nomenclatura

Os nomes de campos Java usam lowerCamelCase:

String firstName;       // good
String first_name;      // not Java style
String FirstName;       // looks like a class

Booleanos costumam ter prefixos is ou has (isPublished, hasIndex), tornando os locais de chamada mais legíveis: if (book.isPublished). Constantes — campos que não mudam — são escritas em UPPER_SNAKE_CASE e marcadas com static final, abordadas nos capítulos sobre static e final.

Campos de instância vs. campos de classe

Por padrão, os campos pertencem a cada instância — cada objeto tem sua própria cópia. Adicione static e o campo passa a pertencer à classe em si; há exatamente uma cópia, compartilhada por todas as instâncias:

public class Counter {
  int count;            // instance — each Counter has its own
  static int total;     // class    — one shared by all Counters
}

Counter a = new Counter();
Counter b = new Counter();
a.count++;   b.count++;   b.count++;
Counter.total++;

System.out.println(a.count);          // 1
System.out.println(b.count);          // 2
System.out.println(Counter.total);    // 1, accessed through the class

Você verá a história completa no capítulo sobre static; por enquanto, assuma que todo campo é um campo de instância, a menos que seja explicitamente marcado com static.

Campos públicos geralmente são um erro

O Java permite que você escreva public String title; e deixe código externo acessar e modificar o campo diretamente. Na prática, você quase nunca faz isso. Uma vez que um campo é público, você perde a capacidade de validar escritas, mudar o tipo mais tarde ou envolver leituras com lógica — qualquer um que toque o campo fica acoplado à sua representação atual.

O padrão padrão é marcar os campos como private e expor getters e setters em vez disso:

public class Book {
  private String title;

  public String getTitle()          { return title; }
  public void   setTitle(String t)  { this.title = t; }
}

Isso é encapsulamento. Os capítulos sobre encapsulamento e getters & setters cobrem o padrão completo. Estamos mostrando campos diretamente nos exemplos iniciais para maior clareza, mas o código Java real os mantém privados.

Campos armazenam referências, não objetos

Quando o tipo de um campo é uma classe (não um primitivo), o campo é uma referência. Dois objetos podem compartilhar o mesmo objeto subjacente por meio de seus campos:

public class Author { String name; }
public class Book   { Author author; }

Author a = new Author();
a.name = "Joshua Bloch";

Book b1 = new Book();   b1.author = a;
Book b2 = new Book();   b2.author = a;     // same Author object

a.name = "J. Bloch";
System.out.println(b1.author.name);   // J. Bloch
System.out.println(b2.author.name);   // J. Bloch

Os mesmos avisos do capítulo anterior se aplicam: isso às vezes é o que você quer e às vezes é um bug. Se um Book deve ter seu próprio Author, você atribuiria new Author() a cada um.

Um exemplo prático

java— editable, runs on the server

O que vem a seguir

Os campos são o estado de um objeto. A outra metade — seu comportamento — vive nos métodos declarados na classe. O próximo capítulo sobre métodos de classe mostra como associar métodos a instâncias e como eles acessam os campos que você acabou de definir.

Prática

Prática
Um campo de instância do tipo int é declarado mas nunca atribuído. Qual valor ele contém quando você o lê por meio de um objeto recém-criado?
Um campo de instância do tipo int é declarado mas nunca atribuído. Qual valor ele contém quando você o lê por meio de um objeto recém-criado?
Was this page helpful?