Skip to content

Attributes and Methods — Junior

What? Attributes are the data a class holds (also called fields or instance variables); methods are the operations the class can perform. How? Declare attributes inside the class body with a type and a name; declare methods with a return type, a name, a parameter list, and a body. Attributes belong to the object, methods describe what the object can do.


1. The two halves of every class

public class BankAccount {

    // ── Attributes (the "what does it know?")
    private String owner;
    private long balanceCents;

    // ── Methods (the "what can it do?")
    public void deposit(long cents) {
        balanceCents += cents;
    }

    public long getBalance() {
        return balanceCents;
    }
}

Reading the class top-to-bottom: first the data the object remembers, then the operations on that data. This top-to-bottom layout is a convention — fields, constructors, methods — and almost every Java codebase follows it. Stick with it; readers' eyes will thank you.


2. Anatomy of an attribute (field)

[modifiers] Type name [= initialValue];

Examples:

public  static final  double PI = 3.14159;     // class constant
private               int    count;             // instance field, default 0
private final         String id   = UUID.randomUUID().toString();
volatile              boolean stop;

Each piece:

  • Modifiers: visibility (public, protected, private, none = package), static, final, transient, volatile.
  • Type: any primitive (int, long, double, ...) or reference type.
  • Name: lowerCamelCase by convention. Constants (static final) use UPPER_SNAKE_CASE.
  • Initial value (optional): an expression evaluated at construction (or at class load time for static).

If you don't initialize, the field gets its default value:

Type Default
byte/short/int/long 0
float/double 0.0
char ''
boolean false
reference null

3. Anatomy of a method

[modifiers] ReturnType name([parameters]) [throws ExceptionList] {
    // body
    return value;          // omitted if return type is void
}

Examples:

public int add(int a, int b) {
    return a + b;
}

private static String format(long cents) { ... }

public void send(Message m) throws IOException { ... }

public boolean isEmpty() {                       // boolean getter, named `isXxx`
    return size == 0;
}

Pieces:

  • Modifiers: visibility, static, final, abstract, synchronized, native, default (interface only).
  • Return type: any type, or void. (Constructors omit this entirely.)
  • Name: lowerCamelCase, verb or verb-phrase.
  • Parameters: zero or more Type name pairs, separated by commas.
  • throws clause: checked exceptions the method may propagate.
  • Body: the code that runs. May return a value of the declared type.

4. Instance vs static — the most-mixed-up rule

Instance members belong to each object:

public class Counter {
    private int count;                  // each Counter has its own count

    public void increment() { count++; }
}

Counter a = new Counter();
Counter b = new Counter();
a.increment();
a.increment();
b.increment();

System.out.println(a.count);   // 2
System.out.println(b.count);   // 1

Static members belong to the class itself — there is one copy, shared by all instances:

public class Counter {
    private static int total;           // ONE total, shared across all Counters

    public static void incrementTotal() { total++; }
    public static int getTotal()        { return total; }
}

Counter.incrementTotal();
Counter.incrementTotal();
Counter c = new Counter();
c.incrementTotal();                     // works, but unusual — call via class name
System.out.println(Counter.getTotal()); // 3

Rules of thumb:

  • Data that varies per object → instance field.
  • Data shared by all (a constant, a counter across the program) → static field.
  • Behavior that uses instance state → instance method.
  • Behavior that doesn't need an instance (utility, factory) → static method.

A static method cannot access instance fields — there's no this. The compiler will reject it.


5. Method signature — the part the compiler cares about

A method's signature is its name + parameter types (in order). The return type and exception list are not part of the signature for overload resolution.

public int  add(int a, int b)    { ... }   // signature: add(int, int)
public long add(long a, long b)  { ... }   // signature: add(long, long) — different
public int  add(int b, int a)    { ... }   // ❌ same as the first — duplicate signature
public long add(int a, int b)    { ... }   // ❌ same signature, different return type — illegal

Two methods can coexist in one class only if their signatures differ. Otherwise — compile error.


6. Parameters: pass-by-value, even for objects

Java is always pass-by-value. The catch: when the value happens to be a reference, the reference is copied — not the object it points to.

void renameTo(User u, String name) {
    u.setName(name);             // ✓ mutates the caller's object via the reference
    u = new User("Bob");         // reassigns LOCAL parameter — caller doesn't see this
}

Inside renameTo, u is a local variable holding a copy of the caller's reference. Mutating through it is visible to the caller (same object). Reassigning it is not.

For primitives:

void doubleIt(int x) { x = x * 2; }     // x is a local copy; caller's int is unchanged

Internalize this once and 80% of "why didn't my method change my variable?" questions disappear.


7. Return values

public int sum(int[] xs) {
    int total = 0;
    for (int x : xs) total += x;
    return total;             // returning the value
}

Notes:

  • A non-void method must return on every path. Falling off the end is a compile error.
  • Returning null from a reference-typed method is legal but often a smell. Prefer empty collections, Optional, or sensible defaults.
  • A void method does not need a return; you can use return; (no value) to exit early.

8. Calling methods: obj.method() vs Class.method()

account.deposit(100);            // instance call — needs an object
Math.max(3, 5);                  // static call — no object required
"hello".length();                 // instance call on a String literal
Integer.parseInt("42");          // static call on the wrapper class

For static calls you can also write obj.staticMethod() — but don't. It misleads readers into thinking it's an instance call. Always call statics via the class name.


9. Constructors call methods, methods call methods

Methods can call each other freely; the order in the source doesn't matter. (Java is not C — no forward declarations needed.)

public class TextBox {
    private final List<String> lines = new ArrayList<>();

    public void add(String text) { lines.add(normalize(text)); }
    public int size()             { return lines.size(); }

    private String normalize(String s) { return s.strip().toLowerCase(); }
}

Constructors can call other constructors via this(...) (must be the first statement) or call helper methods after. Avoid calling overridable methods from a constructor — the subclass override may run before the subclass's own state is ready.


10. Getters and setters — the defaults to learn first

The textbook pattern for a mutable property:

public class Person {
    private String name;
    private int    age;

    public String getName()        { return name; }
    public void   setName(String n){ this.name = Objects.requireNonNull(n); }

    public int  getAge()           { return age; }
    public void setAge(int a) {
        if (a < 0) throw new IllegalArgumentException("age < 0");
        this.age = a;
    }
}

Conventions:

  • Boolean getter is isXxx(), not getXxx().
  • Setter validates the input — that's the whole point of having a setter instead of a public field.
  • Don't add a setter just because you "might" need one. Only when you actually do.

In modern Java, prefer records for immutable carriers (no setters at all):

public record Person(String name, int age) {}
person.name();   // not getName() — record accessor

11. this.field and this.method(...)

this is the implicit reference to the current object. You only need it when there's a name collision:

public Person(String name) {
    this.name = name;        // distinguishes field from parameter
}

You can prefix everything with this. for clarity, but most idiomatic Java omits it when there's no ambiguity. Pick a style and stick to it.


12. Method overloading — same name, different signature

public class Logger {
    public void log(String message)            { ... }
    public void log(String message, Throwable t){ ... }
    public void log(int level, String message) { ... }
}

Overloads are resolved at compile time based on the static types of the arguments. The compiler picks the most specific matching method.

Common pitfall — overloading on primitive vs wrapper:

public void add(int x)     { ... }
public void add(Integer x) { ... }

add(5);                            // calls add(int) — exact match wins
add(Integer.valueOf(5));           // calls add(Integer)
add((Integer) null);               // calls add(Integer) — primitive can't take null

Don't overload on primitive vs boxed. Rename one of them.


13. Final fields and final parameters

public class Order {
    private final long id;                       // assigned exactly once
    public Order(long id) { this.id = id; }
}

public void process(final Order order) {
    // order = somethingElse;     ❌ compile error
    order.cancel();               // ✓ still mutating *through* the reference is fine
}

final on a parameter is local — it has no effect on the caller. It's an in-method readability hint and is required for variables captured by lambdas/anonymous classes (must be effectively final).

final on a field is much stronger — guarantees one assignment and provides JMM safe-publication semantics for immutable objects.


14. Common mistakes for beginners

Mistake Symptom Fix
Forgot static for main (public void main) Main method not found in class ... public static void main(String[] args)
Mixing void with a return value Compile error Match return type to the value
Comparing wrapper objects with == Wrong "not equal" results Use equals or unbox first
static method tries to use instance field Compile error: cannot reference non-static Make it instance, or pass the object
Setter without validation, then bad data flows in Bugs deep in business logic Validate in setter the same as in constructor
Forgetting return on one branch Compile error Either return everywhere or refactor
Re-assigning a parameter expecting caller to see Caller sees no change Return a new value

15. Cheat sheet

// Field
private Type name = init;

// Static constant
public static final Type NAME = value;

// Instance method
public ReturnType name(ParamType p) { ... return value; }

// Static method
public static ReturnType name(ParamType p) { ... return value; }

// Calling
obj.field
obj.method(args)
ClassName.staticField
ClassName.staticMethod(args)

Master attribute and method declarations and you have the structural alphabet of every Java class. Everything else — encapsulation, inheritance, polymorphism — is a rule about how attributes and methods are declared and resolved.