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)¶
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 namepairs, separated by commas. throwsclause: checked exceptions the method may propagate.- Body: the code that runs. May
returna 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:
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-
voidmethod must return on every path. Falling off the end is a compile error. - Returning
nullfrom a reference-typed method is legal but often a smell. Prefer empty collections,Optional, or sensible defaults. - A
voidmethod does not need areturn; you can usereturn;(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(), notgetXxx(). - 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):
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:
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.