Kestrel Exams kestrel logo KESTREL EXAMSPRACTICE TO PASS
Java20 min readCode verified

Java vocabulary: every core term, pointed at in real code

Exams ask what a word means, and the fastest way to answer is to point at it in code. This guide grows one small parking-garage ticket program and labels each term the moment it appears, from literal and operand to instance and static. Every listing was compiled and run on OpenJDK 21.

Practice this topic in the free app →All Java guides

A parking ticket you can point at#

Picture the ticket a parking garage hands you at the gate: plate, minutes, rate, total. You can point at each label. “That is the rate. That is the total.”

Java vocabulary works the same way. Every exam term names something you can point at in code. This guide builds one small program, GarageTicket, for that garage. Each section adds to it, shows the real output, and points at the new words.

First, the four biggest words. A program is a set of instructions a computer follows. The text you type into GarageTicket.java is the source code: instructions written for people, following Java’s rules. The compiler, javac, translates it into bytecode, saved as GarageTicket.class. Bytecode is the same on every computer. The JVM (Java Virtual Machine) is the program that runs bytecode on one particular machine, so one compiled file runs on Windows, macOS and Linux. How Java compiles and runs has the details.

A little history

Java came from James Gosling’s team at Sun Microsystems and was first released in 1995. It began as a project called Oak. Oracle bought Sun in 2010 and maintains Java today.

The first version, labeled#

Here is the smallest useful ticket. Type it rather than paste it; your fingers learn the punctuation faster than your eyes do.

GarageTicket.java
public class GarageTicket {
    public static void main(String[] args) {
        // one ticket: a rate, some hours, a total
        double rate = 3.50;
        int hours = 4;
        double total = rate * hours;
        System.out.println("Total: $" + total);
    }
}
Total: $14.0
Try it first

Before you read the labels: how many statements are inside main? A statement is one complete instruction.

Show the answer

Four: the three lines that make rate, hours and total, and the println line. The comment is not a statement; the compiler ignores it.

WordPoints atWhat it means
Classpublic class GarageTicket { ... }a named container for code, and a blueprint for objects
Methodmain and the lines in its curly bracesa named block of code that does one task; main is where the program starts
Blockany pair of curly braces and what is between thema group of statements; blocks nest inside each other
Statementint hours = 4;one complete instruction, usually ending with a semicolon
Expressionrate * hoursany code that produces a value (here, 14.0)
Comment// one ticket: ...text for people; // runs to the end of the line, /* ... */ can span lines. The compiler ignores both.

An expression produces a value; a statement is a complete instruction. Expressions usually sit inside statements, like rate * hours inside the line that makes total. A bare expression cannot stand alone:

GarageTicket.java
public class GarageTicket {
    public static void main(String[] args) {
        double rate = 3.50;
        int hours = 4;
        rate * hours;
    }
}
GarageTicket.java:5: error: not a statement
        rate * hours;
             ^
1 error

Only assignments, method calls, ++, -- and new may stand alone like that.

Identifiers, keywords, literals and operators#

The compiler reads each line as a row of small units called tokens. Most are one of five kinds: the four in this heading, plus separators (punctuation).

Try it first

A literal is a value typed straight into the code. Point at the literal in double rate = 3.50;, then in System.out.println("Total: $" + total);.

Show the answer

3.50, and "Total: $" with its quotes. rate and total are not literals: they are names, and their values are looked up when the line runs.

Token in double total = rate * hours;KindWhy
doublekeywordreserved by Java with a fixed meaning; here it names a data type
total, rate, hoursidentifiersnames the programmer chose
= and *operatorssymbols that act on values: assign, multiply
rate, hours againoperands of *the values the operator acts on
;separatorpunctuation that ends the statement

An identifier uses letters, digits, _ and $, cannot start with a digit, and is case-sensitive. A keyword such as public or int can never be a name. Keywords are all lowercase; String, System and main are not keywords. Literals come in kinds: 4 (int), 'B' (char), "KTL-4821" (string).

Trap check: true, false and null are not keywords

They are Java’s three reserved literals: values built into the language. Like keywords, they cannot be names. null means “no object”.

The full naming rules and every kind of literal are in identifiers, keywords, literals and variables.

Variables and data types#

A variable is a named place in memory that holds a value, and the value can change. A data type says what kind of value it holds and what you can do with it. int, double, char and boolean, plus byte, short, long and float, are the eight primitive types. A primitive variable holds its value directly: the box called hours has a 4 in it (Java’s primitive types has the details).

Every other type is a reference type. A reference variable holds a reference: an arrow that leads to an object stored elsewhere in memory. String is a class, not a primitive, which is why it is capitalized and has methods such as length().

Try it first

hours was declared as an int. What happens if a later line says hours = "four";?

Show the answer

It does not compile, so the program never runs.

GarageTicket.java
public class GarageTicket {
    public static void main(String[] args) {
        int hours = 4;
        hours = "four";
    }
}
GarageTicket.java:4: error: incompatible types: String cannot be converted to int
        hours = "four";
                ^
1 error

That is static typing: types are declared in the code and checked by the compiler before the program runs. Python is relaxed about it. A Python variable can hold a number on one line and text on the next, because types are only known while the program runs (dynamic typing). Java wants to know up front, and catches the slip before anyone pays for parking.

Declaring, initializing and assigning#

Three words for giving a variable its values:

WordCodeWhat it does
Declarationint hours;introduces a name and a type, with no value yet
Initializationhours = 4;gives the variable its first value
Assignmenthours = hours + 1;gives it a new value later, with the same =

Usually the first two share a line: double total = RATE * hours;. Instantiation, creating an object, is a different word that comes later. The ticket also gains final: a final variable cannot change once set. Capitals mark it as a fixed value here; strictly, the all-capitals convention is for static final constants, which the rate becomes in the last version.

GarageTicket.java
public class GarageTicket {
    public static void main(String[] args) {
        final double RATE = 3.50;     // final: this value never changes
        int hours;                    // declaration
        hours = 4;                    // initialization: the first value
        hours = hours + 1;            // assignment: a new value later
        boolean paid = false;
        String plate = "KTL-4821";
        double total = RATE * hours;  // declaration and initialization together
        System.out.println(plate + " owes $" + total + ", paid: " + paid);
    }
}
KTL-4821 owes $17.5, paid: false

Add the line RATE = 4.00; and the compiler stops with “cannot assign a value to final variable RATE”. That is final doing its job.

Try it first

Below, total gets a value only inside an if. hours is 4, so the if will run. Does it compile?

Show the answer

No. The compiler does not look at the 4. It checks every path through the code, and one path (the condition being false) skips the assignment.

GarageTicket.java
public class GarageTicket {
    public static void main(String[] args) {
        final double RATE = 3.50;
        int hours = 4;
        double total;
        if (hours > 0) {
            total = RATE * hours;
        }
        System.out.println(total);
    }
}
GarageTicket.java:9: error: variable total might not have been initialized
        System.out.println(total);
                           ^
1 error

This rule is definite assignment. A local variable (declared inside a method) gets no automatic value, so the compiler must prove every path assigns it before it is read. Fix: double total = 0;, or add an else.

Concatenation, promotion and casting#

The garage clock counts minutes, and the ticket now records the level as a char. Each version keeps only what its step needs, so the plate and paid drop out here; the plate comes back in the objects section.

Try it first

minutes is 135. Predict the last line: "Minutes + 15: " + minutes + 15.

Show the answer

Minutes + 15: 13515. Here + joins instead of adding, as explained below.

GarageTicket.java
public class GarageTicket {
    public static void main(String[] args) {
        int minutes = 135;
        char level = 'B';
        System.out.println("In hours: " + minutes / 60.0);
        System.out.println("Level after B: " + (level + 1));
        System.out.println("Minutes + 15: " + minutes + 15);
    }
}
In hours: 2.25
Level after B: 67
Minutes + 15: 13515

Concatenation is joining values into one String: when either operand of + is a String, the other becomes text and they are joined. Operators run left to right, so "Minutes + 15: " + minutes is already a String when + 15 arrives. Write (minutes + 15) to add first.

Trap check: is there a String on either side of this +?

Two numbers: + adds. A String on either side: it joins. Work left to right, one + at a time.

The first two lines show promotion: before an operator runs, Java automatically converts its operands to a wider type. A narrower type is widened to match the other, and byte, short and char always become at least int. In minutes / 60.0, 135 becomes 135.0, so the answer is 2.25. In level + 1, the char 'B' is stored as 66 and promoted to an int, so it prints 67.

Trap check: integer or floating-point division?

minutes / 60.0 has a double, so it gives 2.25. minutes / 60 would divide an int by an int and give 2.

Now the bill. The garage charges for every started hour, so 2 hours 15 minutes pays for 3 hours. Predict: 3 × $3.50 is $10.50.

GarageTicket.java
public class GarageTicket {
    public static void main(String[] args) {
        final double RATE = 3.50;          // dollars per started hour
        int minutes = 135;
        double exact = minutes / 60.0;     // widening: 135 becomes 135.0 first
        int hours = (int) exact;           // narrowing: needs a cast, drops the .25
        System.out.println("Exact hours: " + exact);
        System.out.println("Billed hours: " + hours);
        System.out.println("Total: $" + RATE * hours);
    }
}
Exact hours: 2.25
Billed hours: 2
Total: $7.0

A cast is a conversion you write yourself: the type in parentheses before the value, as in (int) exact. Converting int to double is widening: nothing can be lost, so Java does it silently. Converting double to int is narrowing: the fraction would be lost, so Java refuses unless you write the cast. Without it, the compiler reports incompatible types: possible lossy conversion from double to int. A cast to int truncates; it does not round. (Math, rounding and casting has every case.)

Does $7.0 make sense? No: the car stayed more than 2 hours, so the bill must beat 2 × $3.50 = $7.00. The program ran happily and printed a wrong answer, and only the prediction caught it. Do the same check when a tool or an AI hands you an answer.

Syntax errors and logic errors#

A syntax error breaks Java’s grammar, like a sentence with no verb. The compiler cannot translate the file, so no .class file is made and nothing runs. Leave the closing parenthesis off a println and the compiler reports ')' or ',' expected (older JDKs say just ')' expected). A caret ^ marks the spot (the first five errors shows more).

A logic error is the opposite: the code compiles and runs, and the result is wrong. The $7.0 bill is a logic error. The compiler cannot catch it, because it has no idea what the garage meant to charge. (No driver will report this bug either.)

The compiler also rejects grammatical code that is wrong in other ways, such as hours = "four" or a misspelled name. All of these are compile-time errors, and many exams loosely call them syntax errors. A run-time error, such as dividing an int by zero, stops a running program with an exception, Java’s way of reporting a problem while the program runs.

Methods, parameters and arguments#

The bill needs a round-up calculation that every ticket will use, so it gets its own method: a named block of code that does one task, can take input, and can hand back a value.

Try it first

The new method’s header, its first line up to the opening curly brace, is static int billedHours(int mins). Ignore static for now. Which int is the type of the answer, and which part is the input?

Show the answer

The int before the name is the return type: it hands back an int. int mins in the parentheses declares the parameter, which receives the input.

GarageTicket.java
public class GarageTicket {
    static int billedHours(int mins) {         // mins is the parameter
        return (mins + 59) / 60;               // every started hour counts
    }

    public static void main(String[] args) {
        final double RATE = 3.50;
        System.out.println(billedHours(135));  // 135 is the argument
        System.out.println(billedHours(60));
        System.out.println(billedHours(61));
        int minutes = 135;
        int hours = billedHours(minutes);      // minutes is the argument
        System.out.println("Total: $" + RATE * hours);
    }
}
3
1
2
Total: $10.5
WordPoints atWhat it means
Return typethe int before billedHoursthe type handed back; void, as in main, means nothing is handed back
Parameterint mins in the headera variable declared in the method header
Argument135, 60, 61, minutesthe actual value passed in a call
Return statementreturn (mins + 59) / 60;ends the method and hands the value back to the call

To keep the pair apart: the parameter is the placeholder in the header; the argument is the actual value in the call. In the last call, the value of the argument minutes is copied into the parameter mins.

Trap check: integer division, on purpose

(mins + 59) / 60 divides an int by an int, so the fraction is dropped. Adding 59 first pushes any started hour past the next multiple of 60, so the result rounds up.

Shrink it to the smallest case. Try the edges by hand. mins 0: 59 / 60 is 0, no charge. 1: 60 / 60 is 1. 60: 119 / 60 is 1. 61: 120 / 60 is 2. The output agrees, and 135 minutes now bills the $10.5 we predicted. Nothing in the method is about cars: a boat dock billing by the started hour could call it unchanged.

Classes, objects and static#

A garage has many tickets at once, each with its own plate and minutes, all sharing one rate. A class is the blueprint: what data each object holds and what it can do. An object, also called an instance, is one thing built from it. Creating one with new is instantiating the class. Variables declared in the class but outside every method, like plate and minutes, are fields: each object gets its own copy. The dot in first.plate reads as “this ticket’s own”: the plate of the ticket that first leads to.

Try it first

Read main first. How many ticket objects exist? And after same.minutes = 200;, what does the first ticket owe?

Show the answer

Two: count the new keywords. same = first copies the arrow, not the ticket, so the first ticket now has 200 minutes: 4 hours, $14.0.

GarageTicket.java
public class GarageTicket {
    static final double RATE = 3.50;    // static: one rate for the whole garage

    String plate;                       // fields: every ticket has its own
    int minutes;

    static int billedHours(int mins) {
        return (mins + 59) / 60;
    }

    double total() {                    // instance method: works on one ticket
        return RATE * billedHours(minutes);
    }

    void printReceipt() {
        System.out.println(plate + "\tOwes $" + total() + "\n\"Thank you\"");
    }

    public static void main(String[] args) {
        GarageTicket first;                // declare: no ticket exists yet
        first = new GarageTicket();        // instantiate: one ticket object
        first.plate = "KTL-4821";
        first.minutes = 135;

        GarageTicket second = new GarageTicket();
        second.plate = "RVN-0937";
        second.minutes = 50;

        GarageTicket same = first;         // a second arrow, not a new ticket
        same.minutes = 200;

        first.printReceipt();
        second.printReceipt();
        System.out.println(first);
    }
}
KTL-4821	Owes $14.0
"Thank you"
RVN-0937	Owes $3.5
"Thank you"
GarageTicket@266474c2
WordPoints atWhat it means
Instantiatenew GarageTicket()builds one object and gives back an arrow to it
Reference variablefirst, second, sameeach holds an arrow to a ticket, not the ticket
Instance methodtotal(), called as first.total()works on one object, using that object’s fields
Static memberRATE and billedHoursa member (a field or a method) that belongs to the class itself: one shared copy

minutes holds its number directly; first holds an arrow, and same = first copied the arrow. The last line is shown on purpose. Printing a reference variable gives the class name, an @ and a hash code: a number computed from the object, shown in hexadecimal (base 16). Yours will differ. It is not the object’s address, and it is not the arrow the variable holds.

static means the member belongs to the class rather than to any one object, so GarageTicket.RATE works with no ticket at all. That is why main is static: when the program starts, no object exists yet (anatomy of a Java program takes that line apart). That, plus void from the methods section, explains two words you have typed since your first program. On RATE, final means “cannot change” and static means “one shared copy”. Fields, unlike local variables, start with a default value (0, false or null), so the compiler lets you read a field you never assigned. The exception is a final field: it must be given a value, like RATE here.

Escape sequences and scope#

Now the \t and \n in printReceipt. Some characters cannot be typed into a string literal: Enter would break the line of code, and a " would end the string. An escape sequence is a backslash plus one character, standing for one special character: \n a newline, \t a tab, \" a double quote, \\ one backslash. It is always the backslash; /n is just two ordinary characters. More in print, println and printf.

Type this one yourself

Without pasting, write one println statement that prints Spot:, a tab and B-14, then on a second line the word Reserved inside double quotes.

Show the answer
System.out.println("Spot:\tB-14\n\"Reserved\"");

The \n starts the second line, and each \" prints a quote instead of ending the string.

Scope is the region of a program where a name can be seen and used. A variable declared inside a block exists from its declaration to that block’s closing curly brace. A parameter’s scope is its method’s body, so mins exists only inside billedHours; using it in main gets “cannot find symbol”. Variable scope, the stack and the heap goes further.

Abstract data type: what, not how#

One last word. An abstract data type (ADT) describes a type by its operations: what you can do with it. It says nothing about how its data is stored. The garage’s entrance sign is one: a car comes in, a car leaves, and “how many spaces are free?”. Inside, it might keep one counter or one true-or-false value per space; drivers cannot tell, because the operations are the same.

Each storage choice is an implementation of the ADT. A Java class is one way to write one: its methods are the operations, its fields the hidden storage. “Abstract” here means “described without the details”. It is not the keyword abstract, which marks a class you cannot instantiate (see abstract classes and interfaces).

What was new in this guide#

  1. Program, source code, bytecode, JVM; class, method, block, statement, expression and comment.
  2. Identifier, keyword, literal, operator and operand, and the reserved literals true, false and null.
  3. Variable, data type, primitive versus reference, and static versus dynamic typing.
  4. Declaration, initialization, assignment, final and definite assignment.
  5. Concatenation, promotion, casting, widening and narrowing; syntax versus logic errors.
  6. Method, return type, parameter and argument.
  7. Class, object, instance, instantiate, field and static.
  8. Escape sequences, scope and the abstract data type.
One sentence to carry into the exam

Every Java term names something you can point at: a name you chose is an identifier, a value typed in is a literal, a symbol that acts is an operator, code that produces a value is an expression, and a complete instruction is a statement. When a definition question feels slippery, write one short line of code and point.

Where these go wrong#

  • Calling true, false or null keywords. They are the three reserved literals. You still cannot use them as names.
  • Swapping parameter and argument. The parameter is declared in the header; the argument is the value in the call.
  • Thinking GarageTicket desk = gate; makes a second ticket. It copies the reference. Count new to count objects.
  • Reading a local variable that some path never assigned. “Might not have been initialized”. Initialize it where you declare it.
  • Expecting "Minutes: " + m + 15 to add. Once a String is on the left, each later + joins. Use parentheses.
  • Using static to mean “cannot change”. That is final. static means one copy, owned by the class.

On the exam: The wrong options in a vocabulary question are usually the definitions of neighboring words, such as the definition of a keyword offered for “literal”. For each option, ask which word it really defines. If unsure, write int hours = 4; in the margin and point. Read the question twice, answer, then reread to check you answered all of it.

Practice#

Answer each one on paper before you look at the solutions. Every answer that involves running code was checked by compiling and running it.

  1. Predict all three lines of output.
    int level = 3;
    char row = 'D';
    System.out.println("Spot " + level + row);
    System.out.println(level + row + " spot");
    System.out.println("Spot " + (level + 1));
  2. Label every token in final int MAX_MINUTES = 24 * 60; as keyword, identifier, operator, literal or separator. Which part is an expression? Is the line a declaration, an initialization, or both?
  3. This does not compile. Find the error, name the rule, and fix it with one change to main.
    public class GarageTicket {
        int minutes = 90;
    
        double total() {
            return 3.50 * ((minutes + 59) / 60);
        }
    
        public static void main(String[] args) {
            System.out.println(total());
        }
    }
  4. Write a static method levelsNeeded(int cars, int spotsPerLevel) that returns how many levels a garage needs; a partly full level still counts. For the call levelsNeeded(120, 50), name the parameters and the arguments.
  5. What does this print, and which ticket does each variable point at by the end? GarageTicket has one field, int minutes.
    GarageTicket gate = new GarageTicket();
    GarageTicket desk = gate;
    desk.minutes = 90;
    gate = new GarageTicket();
    gate.minutes = 30;
    System.out.println(desk.minutes + " " + gate.minutes);
  6. Syntax error, other compile-time error, or logic error? One sentence each. (a) int hours = (mins + 59) / 60 with no semicolon. (b) double total = RATE + hours; where multiplying was meant. (c) int hours = (int) (minutes / 60.0); where every started hour is billed. (d) System.out.println(totl); where the variable is named total.

Solutions#

  1. In line 1 a String comes first, so both + operators join. In line 2, level + row runs first with two numeric operands, so 'D' (68) is promoted and added: 71. In line 3 the parentheses force the addition. GarageTicket.java
    public class GarageTicket {
        public static void main(String[] args) {
            int level = 3;
            char row = 'D';
            System.out.println("Spot " + level + row);
            System.out.println(level + row + " spot");
            System.out.println("Spot " + (level + 1));
        }
    }
    Spot 3D
    71 spot
    Spot 4
  2. Keywords: final, int. Identifier: MAX_MINUTES. Operators: =, *. Literals: 24 and 60, which are also the operands of *; and ; is a separator. 24 * 60 is an expression worth 1440. The line declares and initializes in one statement, and final makes any later assignment a compile error.
  3. total is an instance method, so it needs a ticket to work on. main is static and has none: GarageTicket.java
    public class GarageTicket {
        int minutes = 90;
    
        double total() {
            return 3.50 * ((minutes + 59) / 60);
        }
    
        public static void main(String[] args) {
            System.out.println(total());
        }
    }
    GarageTicket.java:9: error: non-static method total() cannot be referenced from a static context
            System.out.println(total());
                               ^
    1 error
    Instantiate a ticket and call the method on it:
    GarageTicket t = new GarageTicket();
    System.out.println(t.total());
    It prints 7.0: 90 minutes is 2 started hours, and 2 × 3.50 is 7.0.
  4. Same round-up idea as billedHours: add one less than the divisor, then divide. GarageTicket.java
    public class GarageTicket {
        static int levelsNeeded(int cars, int spotsPerLevel) {
            return (cars + spotsPerLevel - 1) / spotsPerLevel;
        }
    
        public static void main(String[] args) {
            System.out.println(levelsNeeded(120, 50));
            System.out.println(levelsNeeded(100, 50));
            System.out.println(levelsNeeded(0, 50));
        }
    }
    3
    2
    0
    0 cars needing 0 levels is the shrink-it check. The parameters are cars and spotsPerLevel; the arguments are 120 and 50.
  5. desk = gate copies the arrow, so 90 goes into the first ticket. Then gate is pointed at a brand-new second ticket, which gets 30. By the end, desk points at the first ticket and gate at the second. GarageTicket.java
    public class GarageTicket {
        int minutes;
    
        public static void main(String[] args) {
            GarageTicket gate = new GarageTicket();
            GarageTicket desk = gate;
            desk.minutes = 90;
            gate = new GarageTicket();
            gate.minutes = 30;
            System.out.println(desk.minutes + " " + gate.minutes);
        }
    }
    90 30
  6. (a) Syntax error: the grammar needs the semicolon. (b) Logic error: adding is legal, so it runs and prints a wrong total. (c) Logic error: the cast truncates, so 135 minutes bills 2 hours, not 3. (d) A compile-time error, “cannot find symbol”: the grammar is fine, but no variable is called totl. Many exams would call it a syntax error too.

Test-readiness checklist#

These are the items from the course’s Exam 1 topic list that this guide covers. Tick each one only when you can do it without looking.

  • ☐  I can label every token in double total = rate * hours; as keyword, identifier, operator, literal or separator, and name the operands.
  • ☐  I can tell a statement from an expression, a parameter from an argument, and initialization from assignment.
  • ☐  I can say what a primitive variable and a reference variable each hold, and count objects by counting new.
  • ☐  I can explain static, final, promotion, casting and concatenation, and tell a syntax error from a logic error.

Test yourself in the free Kestrel Exams app

45 practice questions on core Java terminology, with every code answer checked by compiling and running it. Free, offline, no account.

Practice core terminology →

Frequently asked questions#

What is the difference between a parameter and an argument in Java?

A parameter is the variable declared in a method header, such as mins in billedHours(int mins). An argument is the actual value passed when the method is called, such as 135 in billedHours(135). The argument is copied into the parameter.

What is the difference between an expression and a statement in Java?

An expression is code that produces a value, such as rate * hours. A statement is a complete instruction, usually ending in a semicolon, such as double total = rate * hours;. Statements often contain expressions.

What are the three reserved literals in Java?

true, false and null. They cannot be used as names, but they are values built into the language rather than keywords. true and false are the boolean values, and null means a reference that points at no object.

Is String a primitive type in Java?

No. String is a class, so a String variable is a reference type that holds a reference to a String object. The eight primitive types are byte, short, int, long, float, double, char and boolean.

What is the difference between a class and an object in Java?

A class is a blueprint describing what data its objects hold and what they can do. An object, also called an instance, is one concrete thing built from the class with new. One class can produce many objects.

Who created Java, and when was it released?

Java was created by James Gosling and his team at Sun Microsystems and first released in 1995. It began as a project called Oak. Oracle bought Sun in 2010 and maintains Java today.

Suggest a change

Something here not clear? A topic you wish we covered? Tell us. We read every message, and a request is the fastest way to get a guide written: several of these exist because somebody asked.