W3docs

Java Class Attributes (Fields)

Declare instance fields on a Java class, set their initial values, and access them via objects.

A class's attributes are the variables declared inside it — the data each object carries. Most authors call them fields (the Java Language Specification does), and "attribute" is the more general OOP word; they mean the same thing. This chapter is about declaring them, what values they start with, and how to read and write them from outside the class.

Declaring a field

A field looks like a local variable, but it sits in the class body rather than inside a method:

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

Each instance of Book gets its own copy of these four fields. Two books have two separate title strings, two separate pages ints, and so on. They live for as long as the object lives, which is until nothing references it anymore.

Default values

If you don't initialize a field, Java initializes it for you. The defaults depend on the type:

TypeDefault
byte, short, int, long0
float, double0.0
char'�' (the null character)
booleanfalse
any object typenull
Book b = new Book();
System.out.println(b.title);    // null
System.out.println(b.pages);    // 0
System.out.println(b.inPrint);  // false

This is one major place fields differ from local variables inside methods — local variables get no default, and the compiler refuses to let you read one before you assign to it. Fields always start with something.

Inline initializers

You can give a field a value right where you declare it:

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

The initializer runs once per object, when that object is created. It runs in declaration order, before the constructor body. If a field needs more complex setup, that's the constructor's job.

Reading and writing fields

You use <reference>.<field> from outside, and just <fieldName> (or this.<fieldName>) from inside the class itself:

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

Inside the class:

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

The this keyword chapter goes into when you need the explicit this. qualifier and when you don't.

Naming conventions

Java field names are lowerCamelCase:

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

Booleans are often named with is or has prefixes (isPublished, hasIndex), making call sites read naturally: if (book.isPublished). Constants — fields that don't change — are written in UPPER_SNAKE_CASE and marked static final, covered in static and final.

Instance fields vs class fields

By default, fields belong to each instance — each object has its own copy. Add static, and the field belongs to the class itself; there's exactly one copy, shared across all instances:

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

You'll meet the full story in the static chapter; for now, assume every field is an instance field unless explicitly marked static.

Public fields are usually a mistake

Java lets you write public String title; and let outside code reach in and modify it directly. In practice you almost never do. Once a field is public, you've lost the ability to validate writes, change the type later, or wrap reads with logic — anyone who touches the field is hard-coded to its current representation.

The standard pattern is to mark fields private and expose getters and setters instead:

public class Book {
  private String title;

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

This is encapsulation. The encapsulation and getters & setters chapters cover the full pattern. We're showing fields directly in early examples for clarity, but real Java code keeps them private.

Fields hold references, not objects

When a field's type is a class (not a primitive), the field is a reference. Two objects can share the same underlying object through their fields:

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

The same warnings from the previous chapter apply: this is sometimes what you want and sometimes a bug. If a Book should have its own Author, you'd assign new Author() to each.

A worked example

java— editable, runs on the server

What's next

Fields are an object's state. The other half — its behavior — lives in methods declared on the class. The next chapter on class methods shows how to attach methods to instances and how they get at the fields you've just defined.

Practice

Practice

An instance field of type int is declared but never assigned. What value does it hold when you read it through a newly-created object?