Java Fields, Attributes and Methods

Java fields store an object's state, while methods describe operations that read or change that state.

Lesson 36 of 127Intermediate14 min read

Java fields store an object's state, while methods describe operations that read or change that state. This distinction helps you decide which values should survive a method call and which should remain temporary. The examples use small counters and tanks to make those lifetimes visible.

Review the related foundation lesson when you need a prerequisite. The complete programs below use Java 17-compatible syntax.

State and behavior

Fields store object state; methods define operations on that state. Attribute is an informal term often used for a field or exposed property.

A field declaration sits directly inside a class body, not inside a method. Its value can remain available after one call finishes and another begins. An attribute is a common informal name for such a value, but Java's language term is field. A property may instead be represented by accessor methods. Knowing the distinction helps when reading documentation that discusses beans, getters or framework mapping rules.

Local values versus fields

A local variable belongs to a method invocation, while an instance field remains part of the object between calls.

A local variable is created for a particular execution of its enclosing scope. Method parameters are local to that call as well. They are not automatically retained when the method returns. If later calls need a value, assign it to an appropriate field. Conversely, avoid making every intermediate calculation a field: temporary state stored on an object can make later calls depend on accidental leftovers.

Operations that preserve rules

A method should maintain the rules of the object. A tank refill operation can reject negative quantities instead of letting callers corrupt the stored level.

Methods can express the object's allowed operations rather than expose unrestricted writes. For a tank, add should reject negative litres before changing its level. A getter can return the current level without granting access to the field itself. Validation belongs before mutation so a rejected operation leaves the original state intact. This order also makes exceptions easier for the caller to handle correctly.

Static versus instance members

Static members describe class-wide state or behavior. An individual tank capacity or current level normally belongs to an instance, not a shared static field.

A static method has no implicit object receiver. A static utility can calculate a value from its parameters, but it cannot directly read a particular tank's instance field. Static fields are suitable for genuinely shared values such as an immutable unit label, not separate water levels. Distinguish static from final: static concerns ownership; final restricts reassignment and does not by itself make a referenced object immutable.

Running the examples

Save name.java, compile it with javac --release 17 name.java, and run java name. Use each program's own public class name and filename.

How TankOperations produces its output

The tank begins with a zero level. add receives twelve, validates that it is nonnegative, and updates the stored field. A later call receives eight and adds it to the same field, producing twenty. litres returns that current value. The method parameter changes between calls, while the object's level remains available to the next call.

How VisitCounter produces its output

Each recordVisit call creates a new previous local variable, but both calls operate on the same visits field. The first call remembers zero and increments visits to one. The second remembers one and increments visits to two. Returning previous reports the value before the update. Making visits local instead would lose the accumulated count.

How CapacityCalculator produces its output

remaining has no stored capacity field and does not require a CapacityCalculator instance. Each call supplies both quantities explicitly, so subtracting used from capacity gives eighteen and thirteen. The calculation is independent of earlier calls. In contrast, a tank method that updates the tank's own stored level belongs to an instance.

Design an operation instead of exposing storage

Consider a counter with a private count field and an increment method. A caller should not need to know whether the count is later stored as an int or calculated from another data source. Its useful contract is the ability to record a visit and read the current total. If a reset operation is allowed, publish it deliberately rather than allowing arbitrary field writes. For practice, add a capacity field to Tank and reject additions that would exceed it. Test an exact-capacity addition and one litre beyond capacity. Decide whether a rejected addition leaves the tank unchanged, then implement that rule consistently.

Java Summary

  • Fields store object state; methods define operations on that state. Attribute is an informal term often used for a field or exposed property.
  • A local variable belongs to a method invocation, while an instance field remains part of the object between calls.
  • A method should maintain the rules of the object. A tank refill operation can reject negative quantities instead of letting callers corrupt the stored level.
  • Static members describe class-wide state or behavior. An individual tank capacity or current level normally belongs to an instance, not a shared static field.
  • Continue with Java exercises, Java quizzes and the Java study roadmap.

Java Examples

Each example shows the code, the output it produces and what each part does.

Example 1

Java Fields, Attributes and Methods in a complete program

Java
public class TankOperations  {
    static class Tank  {
        private int level;
        void add(int litres)  {
            if (litres < 0) throw new IllegalArgumentException();
            level += litres;
        }
        int litres()  {
            return level;
        }
    }
    public static void main(String[] args)  {
        Tank tank = new Tank();
        tank.add(12);
        tank.add(8);
        System.out.println("Litres: " + tank.litres());
    }
}
Output
Litres: 20
Line-by-line explanation
  1. Line 16Evaluates "Litres: " + tank.litres() and prints Litres: 20.
Example 2

A local value does not reset a field

Java
public class VisitCounter  {
    private int visits;
    int recordVisit()  {
        int previous = visits;
        visits++;
        return previous;
    }
    public static void main(String[] args)  {
        VisitCounter counter = new VisitCounter();
        System.out.println(counter.recordVisit());
        System.out.println(counter.recordVisit());
    }
}
Output
0
1
Line-by-line explanation
  1. Line 10Evaluates counter.recordVisit() and prints 0.
  2. Line 11Evaluates counter.recordVisit() and prints 1.
Example 3

A static utility uses supplied arguments

Java
public class CapacityCalculator  {
    static int remaining(int capacity, int used)  {
        return capacity - used;
    }
    public static void main(String[] args)  {
        System.out.println(remaining(30, 12));
        System.out.println(remaining(20, 7));
    }
}
Output
18
13
Line-by-line explanation
  1. Line 6Evaluates remaining(30, 12) and prints 18.
  2. Line 7Evaluates remaining(20, 7) and prints 13.

Java FAQ

Do fields receive default values?

Instance and static fields receive defaults such as zero, false and null before explicit initialization. Local variables do not have usable automatic defaults; Java requires definite assignment before reading them. Do not rely on a field's default when your object's contract requires an explicit starting value.

Does a getter prevent every mutation?

A getter returning a primitive or an immutable value does not expose mutable state directly. Returning an internal mutable list can still allow callers to change it. Return an appropriate copy or immutable representation when the object needs to control those changes.

What are accessors and mutators?

An accessor, often called a getter, returns information about an object, such as getLevel() or, for booleans, isFull(). A mutator changes the object's state, such as add(12) or setName("Kai"). Good mutators check their input so the object stays valid.

Should fields ever be public?

Rarely. Public fields let any code change an object's state without checks, and you can't later add validation without changing every caller. Constants declared public static final are the common exception. Records give a compact alternative when you want simple, read-only data.

When should a method be static instead of an instance method?

Make a method static when it depends only on its parameters and not on any object's fields, like Math.max or a capacity calculator. If the method reads or changes an object's state, it should be an instance method called on that object.

Java Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Multiple choiceeasy

A tank's level must survive between add calls. Where should it be stored?

Multiple choicemedium

Which declaration shares one value across instances?

Java Quiz

2 questions to check what you learned.

  1. Why validate a negative addition before changing a tank field?

    • To preserve the previous state when rejecting the input
    • To make the field local
    • To prevent all future additions
  2. What is true about final and static?

    • They express different restrictions and can be combined
    • final always means class-wide ownership
    • static always makes an object immutable