Java Class Methods
Add instance methods to a Java class to give objects behavior and operate on their fields.
A class's methods are what give its objects behavior. Fields hold what an object is; methods describe what it can do. Up to now the methods you've written have been static — utilities that belong to the class itself. This chapter is about instance methods, which belong to each object and operate on its fields.
The term "class methods" in Java is a little overloaded. Most authors use it to mean methods defined inside a class — which includes both kinds. A few use it strictly to mean static methods (because those literally belong to the class). We'll cover instance methods here, and static methods get a chapter of their own at Java static.
An instance method
Add a method to the class body, without static, and it becomes part of every instance:
public class Circle {
double radius;
double area() {
return Math.PI * radius * radius;
}
}Now every Circle you create can answer area():
Circle c = new Circle();
c.radius = 5;
System.out.println(c.area()); // 78.539...The body reads radius without qualifying it — Java resolves the bare name as this.radius, the field of the object the method was called on.
this — the receiver
Every instance method has an invisible parameter called this, which refers to the object the method was called on:
Circle a = new Circle(); a.radius = 2;
Circle b = new Circle(); b.radius = 5;
a.area(); // inside area(), this == a, so this.radius == 2
b.area(); // inside area(), this == b, so this.radius == 5The same compiled method runs in both cases; what changes is which object this refers to. The this keyword chapter goes into when you have to write this. explicitly and when you can omit it.
Methods that change state
A method can write to fields too. Such methods are often called mutators:
public class Counter {
int count;
void increment() {
count++; // mutates this.count
}
void reset() {
count = 0;
}
int get() {
return count;
}
}
Counter c = new Counter();
c.increment(); c.increment(); c.increment();
System.out.println(c.get()); // 3Mutation through methods is how objects evolve over time without outside code touching their fields directly. Methods that only read a field and hand it back are the mirror image — they're usually called accessors or getters (int get() above is one). Routing reads and writes through methods, rather than exposing the fields, is the core idea behind encapsulation: the object stays in charge of its own data.
Calling other methods from inside
Instance methods can call other methods on the same object, just by name:
public class Rectangle {
double width, height;
double area() { return width * height; }
double perimeter() { return 2 * (width + height); }
String describe() {
return "area=" + area() + ", perimeter=" + perimeter();
}
}The compiler turns area() and perimeter() inside describe into this.area() and this.perimeter(). They call the methods on whichever rectangle describe was called on.
Static vs instance — which to use
The rule of thumb: does the method depend on per-object state?
- If yes, it's an instance method (no
static). - If no, it's
static.
public class Math2 {
public static int squared(int n) { // pure calculation — static
return n * n;
}
}
public class Counter {
int count;
public void increment() { // reads/writes this.count — instance
count++;
}
}A common smell is an instance method that ignores this entirely — that's a static method wearing a costume. The Java static chapter goes through the trade-offs.
Calling an instance method needs an instance
Because instance methods read this, you can't call one without an object:
Counter.increment(); // ERROR — increment is not static
new Counter().increment(); // fine — increment is called on a fresh Counter (which is then thrown away)
Counter c = new Counter();
c.increment(); // fine — increment is called on cThis is the most common compile error newcomers hit: a non-static method referenced from a static context (typically from main, which is itself static).
If the compiler says non-static method increment() cannot be referenced from a static context, you almost certainly called an instance method without an object — for example Counter.increment() instead of c.increment(). Create an instance first, then call the method on it.
Overloading and overriding
Instance methods support both:
- Overloading: multiple methods with the same name but different parameter lists in the same class (covered in method overloading).
- Overriding: a subclass replacing the inherited version of a method (covered in method overriding).
You've already seen overloading in Part 5. Overriding is one of the big payoffs of inheritance and comes up shortly.
Method bodies are blocks
A method body is just an ordinary block of code — variables you declare are local to the call, control flow works the same as anywhere else, and you can return early. Nothing about "this is in a class" changes how the body itself reads. The only extra capability is that bare identifiers can now refer to the object's fields and other methods.
A worked example
This example puts accessors (area, perimeter), a mutator (scale), and a method that calls other methods (describe) in one class. Rectangle is declared static class only so the whole demo fits in a single file — that keyword applies to the nested class, not to its instance methods, which still run on a specific rectangle. Notice that scaling r leaves s untouched: each object carries its own state.
What's next
So far you've created objects by writing new Dog(), then filling in fields line by line. That's verbose and error-prone — and easy to forget. The fix is a constructor, a special method that runs when the object is created. Continue to the constructors chapter.