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.
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.javapublic 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
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.
| Word | Points at | What it means |
|---|---|---|
| Class | public class GarageTicket { ... } | a named container for code, and a blueprint for objects |
| Method | main and the lines in its curly braces | a named block of code that does one task; main is where the program starts |
| Block | any pair of curly braces and what is between them | a group of statements; blocks nest inside each other |
| Statement | int hours = 4; | one complete instruction, usually ending with a semicolon |
| Expression | rate * hours | any 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:
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).
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; | Kind | Why |
|---|---|---|
double | keyword | reserved by Java with a fixed meaning; here it names a data type |
total, rate, hours | identifiers | names the programmer chose |
= and * | operators | symbols that act on values: assign, multiply |
rate, hours again | operands of * | the values the operator acts on |
; | separator | punctuation 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).
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().
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.
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:
| Word | Code | What it does |
|---|---|---|
| Declaration | int hours; | introduces a name and a type, with no value yet |
| Initialization | hours = 4; | gives the variable its first value |
| Assignment | hours = 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.
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.
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.
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.
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.
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.
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.
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.javapublic 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.
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.
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
| Word | Points at | What it means |
|---|---|---|
| Return type | the int before billedHours | the type handed back; void, as in main, means nothing is handed back |
| Parameter | int mins in the header | a variable declared in the method header |
| Argument | 135, 60, 61, minutes | the actual value passed in a call |
| Return statement | return (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.
(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.
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.
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
| Word | Points at | What it means |
|---|---|---|
| Instantiate | new GarageTicket() | builds one object and gives back an arrow to it |
| Reference variable | first, second, same | each holds an arrow to a ticket, not the ticket |
| Instance method | total(), called as first.total() | works on one object, using that object’s fields |
| Static member | RATE and billedHours | a 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.
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#
- Program, source code, bytecode, JVM; class, method, block, statement, expression and comment.
- Identifier, keyword, literal, operator and operand, and the reserved literals
true,falseandnull. - Variable, data type, primitive versus reference, and static versus dynamic typing.
- Declaration, initialization, assignment,
finaland definite assignment. - Concatenation, promotion, casting, widening and narrowing; syntax versus logic errors.
- Method, return type, parameter and argument.
- Class, object, instance, instantiate, field and
static. - Escape sequences, scope and the abstract data type.
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,falseornullkeywords. 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. Countnewto 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 + 15to add. Once a String is on the left, each later+joins. Use parentheses. - Using
staticto mean “cannot change”. That isfinal.staticmeans 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.
- 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)); - 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? - 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()); } } - 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 calllevelsNeeded(120, 50), name the parameters and the arguments. - What does this print, and which ticket does each variable point at by the end?
GarageTickethas 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); - Syntax error, other compile-time error, or logic error? One sentence each. (a)
int hours = (mins + 59) / 60with 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 namedtotal.
Solutions#
- In line 1 a String comes first, so both
+operators join. In line 2,level + rowruns first with two numeric operands, so'D'(68) is promoted and added: 71. In line 3 the parentheses force the addition. GarageTicket.javapublic 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 - Keywords:
final,int. Identifier:MAX_MINUTES. Operators:=,*. Literals:24and60, which are also the operands of*; and;is a separator.24 * 60is an expression worth 1440. The line declares and initializes in one statement, andfinalmakes any later assignment a compile error. totalis an instance method, so it needs a ticket to work on.mainis static and has none: GarageTicket.javapublic class GarageTicket { int minutes = 90; double total() { return 3.50 * ((minutes + 59) / 60); } public static void main(String[] args) { System.out.println(total()); } }
Instantiate a ticket and call the method on it:GarageTicket.java:9: error: non-static method total() cannot be referenced from a static context System.out.println(total()); ^ 1 error
It printsGarageTicket t = new GarageTicket(); System.out.println(t.total());7.0: 90 minutes is 2 started hours, and 2 × 3.50 is 7.0.- Same round-up idea as
billedHours: add one less than the divisor, then divide. GarageTicket.javapublic 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)); } }
0 cars needing 0 levels is the shrink-it check. The parameters are3 2 0carsandspotsPerLevel; the arguments are120and50. desk = gatecopies the arrow, so 90 goes into the first ticket. Thengateis pointed at a brand-new second ticket, which gets 30. By the end,deskpoints at the first ticket andgateat the second. GarageTicket.javapublic 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- (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.
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.