These questions explain how a small, clear API protects invariants and allows implementation changes without exposing unnecessary mutable state.
Answer: Give each class a coherent responsibility, meaningful names, and a clear contract. Keep related state and operations together, validate invariants at boundaries, and expose only the behavior callers need. Test observable behavior rather than forcing tests to depend on private implementation details.
Use composition and interfaces when they express real variation. Do not add a deep inheritance tree, framework, or design pattern merely to anticipate unspecified future requirements. Profile before optimizing, manage resources explicitly, and define a concurrency policy when mutable state is shared.
Answer: It lets an implementation change while preserving the contract callers rely on. For example, an internal storage representation can change if the public operations keep their specified behavior.
This is not an unconditional promise that every change is compatible. Return values, exceptions, ordering, side effects, thread-safety guarantees, and exposed mutable references may all be part of the effective contract. Encapsulation reduces dependencies on internals; it does not excuse changing documented behavior unnoticed.
Answer: Callers interact through a deliberately chosen API instead of manipulating the object's representation directly. The class controls how valid state is established and changed, and can conceal details such as caches or storage layout.
Private fields help, but returning a mutable internal list can expose the representation again. Consider immutable results, defensive copies, or views with clearly documented behavior. Information hiding is a design property, not merely the number of private keywords in the source.
Answer: It is the API available to callers: accessible types, constructors or factories, operations, and their contracts. The word interface here does not require a declaration using Java's interface keyword.
A concrete class can expose an API, and a Java interface can define part of one. Document intended inputs, results, failures, and ownership of returned data. In modular applications, accessibility may also depend on package exports and module readability.
Answer: No. Keep representation private where appropriate and expose only useful operations. Automatically adding setters can allow callers to violate invariants or couple themselves to implementation fields.
A method such as reserve(quantity) can enforce a meaningful transition more clearly than setAvailable(value). Read-only or immutable objects may need no setters. JavaBean naming conventions matter when a framework expects them, but are not a universal requirement for encapsulated Java classes.
Answer: It directs callers through operations that enforce valid state changes rather than letting them assign arbitrary field values. Those operations can validate inputs and preserve relationships among fields.
public final class StockItem {
private int available;
public StockItem(int available) {
if (available < 0) throw new IllegalArgumentException("Negative stock");
this.available = available;
}
public void reserve(int quantity) {
if (quantity <= 0 || quantity > available)
throw new IllegalArgumentException("Invalid quantity");
available -= quantity;
}
public int available() { return available; }
public static void main(String[] args) {
StockItem item = new StockItem(5);
item.reserve(2);
System.out.println(item.available());
}
}
This prints 3. The class has no arbitrary stock setter. The example assumes thread confinement; private fields and a final class do not automatically make concurrent reservations safe.
Answer: They are methods, not variables. A getter exposes a logical property, which may be computed rather than directly stored. A setter requests a property change and can validate or normalize input.
They are useful where property-style access fits the API, but are not inherently better than behavior-oriented operations. A getter returning an internal mutable object can undermine encapsulation, and a setter that blindly assigns a field may fail to protect invariants.
Answer: Isolate likely sources of change behind clear boundaries, while keeping the current implementation understandable. Prefer focused responsibilities and small contracts over speculative abstractions for every possible future feature.
Composition can support replacement of a collaborator without exposing superclass internals. Immutable data, explicit resource ownership, and consistent error handling also simplify change. Choose inheritance only when subtypes can honor the parent contract, and support changes with tests of the behavior clients actually use.
Answer: For stateful domain objects with invariants, prefer operations that control access rather than exposing writable representation. The correct API need not mirror every field one-for-one.
There are deliberate data-oriented designs, such as immutable records or simple value carriers, where exposed data is appropriate. Even a record is only shallowly immutable when components reference mutable objects. Decide ownership and mutability explicitly instead of assuming one field-access rule fits every kind of class.
Answer: An identifier uses a valid Java identifier-start character followed by valid identifier-part characters; digits cannot be the first character. Java supports Unicode identifiers and is case-sensitive. Reserved keywords and the literals true, false, and null cannot be ordinary identifiers.
Names such as count, _count, and $count are syntactically valid, although dollar signs are normally avoided in handwritten names. A single underscore is reserved and cannot name a variable you later read. Java 25 permits underscore for certain unnamed declarations, where the value cannot be referenced by that name. Contextual keywords also have position-specific restrictions.
References: Access control, Identifiers, and JavaBean discovery conventions.