A program is, in essence, data being transformed. Variables are the containers where you keep that data and types are the rules that determine what fits in each container and which operations make sense with it. In Java these rules are checked before anything runs, and that makes the type system your first safety net: much of what blows up in production in other languages does not even compile here. In this lesson you will learn the eight primitive types, the crucial difference between primitives and references, the special behaviour of String, type conversions, constants and inference with var. By the end you will have modelled the first book of the BiblioTech catalog with variables.
Contents
- Declaration, initialisation and assignment
- The eight primitive types
- Literals: how values are written
- Primitives versus references: what each variable holds
String: the special type- Type conversions
- Wrappers, autoboxing and conversion from text
finaland constants- Type inference with
var - Modelling a BiblioTech book
- Common Mistakes and Tips
- Exercises
- Declaration, initialisation and assignment
Three operations worth telling apart from the start:
int publicationYear; // 1. DECLARATION: we reserve the name and fix the type
publicationYear = 2018; // 2. ASSIGNMENT: we give it a value
int daysLate = 12; // 3. DECLARATION + INITIALISATION on a single line- Declaring is announcing to the compiler: "there will be a variable called
publicationYearthat will hold integers". From then on, the compiler makes sure you do not put anything else in it. - Initialising is giving it its first value.
- Assigning is giving it a value (the first one or any later one). The
=symbol does not mean mathematical equality, but "store what is on the right in the variable on the left".
A rule Java enforces and that is worth celebrating: you cannot read a local variable before assigning it a value.
int daysLate;
System.out.println(daysLate); // COMPILATION ERROR: variable daysLate might not have been initializedOther languages would hand you garbage or undefined; Java refuses to compile. That eliminates a whole family of subtle bugs.
You can declare several variables of the same type on one line, although one per line is preferred for readability:
- The eight primitive types
Java has exactly eight primitive types. They are not objects: they are pure values the JVM manipulates directly and efficiently.
| Type | Category | Size | Range | Default value | Typical use |
|---|---|---|---|---|---|
byte |
Integer | 8 bits | −128 to 127 | 0 |
Binary data, saving memory |
short |
Integer | 16 bits | −32,768 to 32,767 | 0 |
Rarely used |
int |
Integer | 32 bits | −2,147,483,648 to 2,147,483,647 | 0 |
The default integer |
long |
Integer | 64 bits | ±9.22 × 10¹⁸ | 0L |
Timestamps, identifiers, large figures |
float |
Decimal | 32 bits | ~7 significant digits | 0.0f |
Rarely used; insufficient precision |
double |
Decimal | 64 bits | ~15 significant digits | 0.0d |
The default decimal |
char |
Character | 16 bits | 0 to 65,535 (one Unicode character) | ' ' |
A single character |
boolean |
Logical | JVM-dependent | true or false |
false |
Conditions, flags |
Important notes about this table:
- The "default value" column only applies to the fields of a class (module 3), not to local variables inside
main, which as we have just seen must be initialised explicitly. - In practice you will use
int,double,booleanandchar95 % of the time.byte,shortandfloatare special cases. longis essential whenintfalls short. Theintlimit (around 2,147 million) seems enormous until you start counting milliseconds: the number of milliseconds since 1970 overflowedintat 1970 + 24 days.charis not a one-characterString: it is written with single quotes ('A') and it is a numeric type underneath.booleanin Java is not a number. There is no "0 is false, 1 is true" equivalence as in C:if (1)does not compile.
byte sectionCode = 3; // library sections: 1..12
short totalCopies = 850; // books in the Nexus Software catalog
int publicationYear = 2018;
long loanIdentifier = 100000000045L; // the L is mandatory: it does not fit in an int
float bookWeightKg = 0.68f; // the f is mandatory
double fine = 3.75;
char sectionInitial = 'J'; // SINGLE quotes
boolean available = true;
- Literals: how values are written
A literal is a value written directly in the code. Java accepts several notations:
Integer literals
int decimal = 2018; // base 10, the normal one
int hexadecimal = 0x7E2; // base 16, prefix 0x -> 2018
int binary = 0b11111100010; // base 2, prefix 0b -> 2018 (since Java 7)
int octal = 03742; // base 8, prefix 0 -> 2018 (avoid: confusing)
long longCode = 9788498750102L; // L suffix mandatory if it exceeds the int rangeCareful with octal: int x = 010; is 8, not 10. It is a classic source of bugs; avoid leading zeros.
Underscores as separators
Since Java 7 you can use _ to make long numbers readable. The compiler ignores them completely:
int annualBudget = 1_250_000; // reads much better than 1250000
long numericIsbn = 978_000_000_0001L;
int mask = 0b1010_0101_1100_0011;Restrictions: they cannot go at the beginning, at the end, or next to the decimal point.
Decimal literals
double fine = 3.75;
double rate = 0.25d; // the d is optional: double is the default type
float weight = 0.68f; // the f IS mandatory
double scientificNotation = 1.5e3; // 1500.0A rule that causes many errors: a decimal literal without a suffix is a double. That is why float weight = 0.68; does not compile: you are trying to put a double into a float, which is smaller. You have to write 0.68f.
Character and boolean literals
char letter = 'J';
char code = 74; // char is numeric underneath: 74 is 'J' in Unicode
char newline = '\n'; // escape sequence
boolean available = true;
boolean onLoan = false;The most used escape sequences:
| Sequence | Meaning |
|---|---|
\n |
Line break |
\t |
Tab |
\" |
Double quote inside a String |
\' |
Single quote inside a char |
\\ |
Backslash |
- Primitives versus references: what each variable holds
This is one of the most important ideas in the module, and the one that explains many behaviours that otherwise look arbitrary.
Java divides types into two families:
- Primitive types (the eight above): the variable holds the value directly.
- Reference types (
String, arrays, and every class): the variable holds a reference (an address) to an object that lives in another area of memory.
A Java program's memory is organised, in simplified terms, into two areas:
- The stack: fast and small, it holds the local variables of methods.
- The heap: large, it holds the objects. It is where the garbage collector operates.
flowchart LR
subgraph Stack["Stack (local variables of main)"]
A["publicationYear<br/><b>2018</b>"]
B["available<br/><b>true</b>"]
C["title<br/><b>ref → #a1b2</b>"]
D["author<br/><b>ref → #c3d4</b>"]
end
subgraph Heap["Heap (objects)"]
E["#a1b2<br/>String: 'Effective Java'"]
F["#c3d4<br/>String: 'Joshua Bloch'"]
end
C --> E
D --> F
Notice the difference: publicationYear is 2018; title is not the text, but an arrow pointing to it.
Immediate practical consequences:
// With primitives: the VALUE is copied
int daysA = 12;
int daysB = daysA; // daysB receives a copy of the number
daysA = 20;
System.out.println(daysB); // 12 -> daysB was not affected
// With references: the REFERENCE is copied
String titleA = "Effective Java";
String titleB = titleA; // both point to the SAME objectA reference variable can also be null, which means "it points to no object". Primitives can never be null.
String publisher = null; // valid: the reference points to nothing
// int pages = null; // ERROR: an int always holds a numberTrying to use a null reference produces Java's most famous runtime error, NullPointerException. You will deal with it formally in module 6.
String: the special type
String: the special typeString is not a primitive, it is a class. But it gets such privileged treatment from the language that it behaves somewhere in between.
Creation
String title = "Effective Java"; // the normal form, with a literal
String author = new String("Joshua Bloch"); // works, but is NOT usedString is the only class that can be created with a literal, without new. Using new String(...) is an antipattern: it creates an extra object with no advantage at all.
Immutability
A String can never be modified. Every method that "changes" a string actually returns a new string:
String title = "Effective Java";
title.toUpperCase(); // computes "EFFECTIVE JAVA"... and throws it away
System.out.println(title); // still prints "Effective Java"
title = title.toUpperCase(); // CORRECT: we store the result
System.out.println(title); // "EFFECTIVE JAVA"This is one of the most frequent beginner mistakes. If a String method does not seem to do anything, you have almost certainly forgotten to store the result.
Why are they immutable? For safety (a string cannot change under your feet), for efficiency (it allows identical strings to be shared in the string pool) and because it makes them thread-safe at no cost at all (module 8).
Concatenation
String title = "Effective Java";
int publicationYear = 2018;
String card = title + " (" + publicationYear + ")";
System.out.println(card); // Effective Java (2018)The + operator concatenates. When one of the operands is a String, Java automatically converts the other one to text. This also means that "Total: " + 2 + 3 produces "Total: 23" and not "Total: 5": it is evaluated left to right, and as soon as there is a String everything else gets glued on as text. It is fixed with parentheses: "Total: " + (2 + 3).
Essential methods
Starting from:
| Method | What it does | Example | Result |
|---|---|---|---|
length() |
Number of characters | "Effective Java".length() |
14 |
trim() |
Removes leading and trailing spaces | title.trim() |
"Effective Java" |
strip() |
Like trim but Unicode-aware (Java 11+) |
title.strip() |
"Effective Java" |
toUpperCase() |
Everything to uppercase | "java".toUpperCase() |
"JAVA" |
toLowerCase() |
Everything to lowercase | "JAVA".toLowerCase() |
"java" |
substring(i) |
From index i to the end |
"Effective Java".substring(10) |
"Java" |
substring(i, j) |
From index i to j (excluding j) |
"Effective Java".substring(0, 9) |
"Effective" |
equals(other) |
Identical content? | "java".equals("Java") |
false |
equalsIgnoreCase(other) |
Identical ignoring case | "java".equalsIgnoreCase("Java") |
true |
isEmpty() |
Zero length? | "".isEmpty() |
true |
isBlank() |
Empty or only spaces? (Java 11+) | " ".isBlank() |
true |
contains(txt) |
Does it contain that fragment? | "Effective Java".contains("ffec") |
true |
replace(a, b) |
Replaces | "Java".replace('a', 'o') |
"Jovo" |
charAt(i) |
Character at position i |
"Java".charAt(0) |
'J' |
indexOf(txt) |
Position of the first occurrence (−1 if absent) | "Effective Java".indexOf("J") |
10 |
Indexes start at 0, and substring(i, j) includes i but excludes j. It is the convention throughout Java; internalise it now.
An example applied to BiblioTech:
String isbn = "978-0000000001";
System.out.println("Full ISBN: " + isbn);
System.out.println("GS1 prefix: " + isbn.substring(0, 3)); // "978"
System.out.println("Code: " + isbn.substring(4)); // "0000000001"
System.out.println("Length: " + isbn.length()); // 14Text blocks (Java 15+)
For multi-line text there is a triple-quote syntax that avoids \n and concatenations:
String header = """
============================================
BiblioTech - Nexus Software
Library management system
============================================
""";
System.out.println(header);The details: the opening triple quote must be followed by a line break, and the indentation is computed relative to the closing line, so you can indent the block inside your code without those spaces appearing in the output. It is enormously convenient for menus, templates or JSON and SQL fragments.
- Type conversions
When you mix numeric types, Java applies strict rules.
Widening conversion: automatic
It goes from a smaller type to a larger one. No information is lost, so Java does it on its own:
int daysLate = 12;
double daysAsDecimal = daysLate; // automatic: 12.0
System.out.println(daysAsDecimal); // 12.0This explains why 12 * 0.25 gives 3.0: the int is converted to double before multiplying.
Narrowing conversion: requires an explicit cast
It goes from a larger type to a smaller one. It may lose information, so Java forces you to ask for it explicitly with a cast, which is your signature saying "I know what I am doing":
double exactFine = 3.75;
int intFine = (int) exactFine; // cast mandatory
System.out.println(intFine); // 3 <- it is TRUNCATED, not roundedCritical points:
- The cast to an integer truncates, it does not round.
(int) 3.99is3. To round you useMath.round(3.99), which gives4. - If the value does not fit, the result is silent garbage:
There is no error and no warning here: the compiler assumes you knew what you were doing. That is why casts must be used with full awareness.
Promotion in expressions
In an operation between different types, Java promotes to the larger of the two:
int daysLate = 12;
double rate = 0.25;
double fine = daysLate * rate; // int is promoted to double -> 3.0And the classic trap, which we will look at in depth in the operators lesson:
The division is done between integers (giving 2) and only afterwards converted to double. The solution is to force it beforehand: (double) total / parts.
- Wrappers, autoboxing and conversion from text
Every primitive has a wrapper class that represents it as an object:
| Primitive | Wrapper |
|---|---|
byte |
Byte |
short |
Short |
int |
Integer |
long |
Long |
float |
Float |
double |
Double |
char |
Character |
boolean |
Boolean |
What are they for? Two reasons:
- Collections (module 5) only accept objects, not primitives. You cannot have a list of
int, but you can have one ofInteger. - They can be
null, which lets you represent "no value" (an unknown publication year, for example).
Autoboxing and unboxing
Since Java 5, conversion between a primitive and its wrapper is automatic:
Integer yearObject = 2018; // autoboxing: int -> Integer
int yearPrimitive = yearObject; // unboxing: Integer -> intIt is convenient, but it has two costs worth knowing: it uses more memory and, above all, unboxing a null reference throws NullPointerException. Practical rule: use primitives unless you need null or a collection.
Useful static methods on the wrappers
Here is their most immediate use in this module: converting text into a number. Remember that command-line arguments and whatever is read from the console always arrive as String.
String yearText = "2018";
int publicationYear = Integer.parseInt(yearText); // 2018 as a number
String fineText = "3.75";
double fine = Double.parseDouble(fineText); // 3.75 as a number
// Useful constants
System.out.println(Integer.MAX_VALUE); // 2147483647
System.out.println(Integer.MIN_VALUE); // -2147483648
// The reverse conversion: number -> text
String asText = String.valueOf(2018);If the text does not represent a valid number (Integer.parseInt("two thousand")), the program fails at runtime with NumberFormatException. How to catch and handle that failure is studied in module 6; for now it is enough to know it exists and to enter correct data.
final and constants
final and constantsThe word final applied to a variable means that its value cannot change once assigned:
final double DAILY_RATE = 0.25;
DAILY_RATE = 0.30; // COMPILATION ERROR: cannot assign a value to final variableWhy use them:
- They communicate intent. Whoever reads the code knows that value is a business rule, not a variable piece of data.
- They prevent bugs. A value that must not change cannot change by accident.
- They eliminate "magic numbers". Comparing
0.25scattered over twenty places with a singleDAILY_RATEis the difference between changing the rate in a minute or in an afternoon.
Constants are written in UPPERCASE_WITH_UNDERSCORES, as we saw in the previous lesson:
final double DAILY_RATE = 0.25; // euros per day late
final int LOAN_DAYS = 15; // standard loan duration
final double MAX_FINE = 20.0; // fine cap per loan
final String COMPANY_NAME = "Nexus Software";An important nuance for later on: in a reference variable, final prevents reassigning the reference, not modifying the object it points to. With String you do not notice because they are immutable, but with mutable objects (module 3) you do.
- Type inference with
var
varSince Java 10 you can omit the type of a local variable and let the compiler deduce it from the assigned value:
var title = "Effective Java"; // the compiler infers String
var publicationYear = 2018; // infers int
var fine = 3.75; // infers double
var available = true; // infers booleanIt is crucial to understand that var does not turn Java into a dynamically typed language. The type is fixed at compile time and it is as strict as ever:
When to use it and when not to
| Situation | Recommendation | Example |
|---|---|---|
| The type is obvious from the value | Use var |
var scanner = new Scanner(System.in); |
| The type is long and repetitive | Use var |
var catalog = new HashMap<String, Book>(); |
| The type cannot be deduced by reading | Avoid var |
var result = process(data); |
| You want a specific type other than the inferred one | Do not use var |
double rate = 1; (with var it would be int) |
| Simple numeric literals | Debatable; the explicit type is usually clearer | int daysLate = 12; |
Restrictions on var:
- Only for local variables (inside methods). It is not allowed for class fields or parameters.
- It forces initialisation on the same line:
var x;does not compile. - It does not accept
nullas an initial value:var x = null;does not compile, because there is no type to infer.
This course uses explicit types in module 1 (so that you always see which type is in play) and var from module 5 onwards, where generic types make it genuinely useful.
- Modelling a BiblioTech book
Let's apply everything we have learnt. The Nexus Software catalog needs to record, for each book: title, author, ISBN, publication year and availability. With what you know today, that translates into loose variables:
public class BiblioTechCatalog {
public static void main(String[] args) {
// --- BiblioTech business constants ---
final String COMPANY_NAME = "Nexus Software";
final double DAILY_RATE = 0.25; // euros per day late
final int LOAN_DAYS = 15; // standard loan duration
// --- Data of the first book in the catalog ---
String title = "Effective Java";
String author = "Joshua Bloch";
String isbn = "978-0000000001";
int publicationYear = 2018;
boolean available = true;
// --- Data of a loan in progress ---
String employee = "Marta Ruiz";
int elapsedDays = 27;
int daysLate = elapsedDays - LOAN_DAYS; // 12
double fine = daysLate * DAILY_RATE; // int * double -> double
// --- Output ---
System.out.println("=== " + COMPANY_NAME + " - BiblioTech ===");
System.out.println();
System.out.println("Title: " + title);
System.out.println("Author: " + author);
System.out.println("ISBN: " + isbn);
System.out.println("Published: " + publicationYear);
System.out.println("Available: " + available);
System.out.println();
System.out.println("Loaned to: " + employee);
System.out.println("Days late: " + daysLate);
System.out.println("Accrued fine: " + fine + " EUR");
}
}Output:
=== Nexus Software - BiblioTech === Title: Effective Java Author: Joshua Bloch ISBN: 978-0000000001 Published: 2018 Available: true Loaned to: Marta Ruiz Days late: 12 Accrued fine: 3.0 EUR
The limitation you can already feel
This approach works for one book. But Nexus Software has hundreds. With loose variables you would need title1, title2, title3… and nothing would guarantee that author2 really corresponds to title2. Data that forms a conceptual unit is scattered around.
That is exactly the gap object-oriented programming fills: in module 3 you will create a Book class that groups these five variables into a single type, and in module 5 you will store hundreds of those objects in a collection. Notice that the names you are using now (title, author, isbn, publicationYear, available) will literally be the fields of that class. You are laying the foundations.
Common Mistakes and Tips
- Forgetting to store the result of a
Stringmethod.title.toUpperCase();changes nothing. It must betitle = title.toUpperCase();. float x = 3.75;does not compile. Decimal literals aredouble; you have to write3.75f.long x = 10000000000;does not compile. The literal is read as anintand overflows. You have to write10000000000L.- Confusing
'A'with"A". Single quotes meanchar, double quotes meanString. They are not interchangeable. - Expecting
(int) 3.99to be 4. The cast truncates. To round, useMath.round(). - Using
==to compareString. It compares references, not content. You useequals(). It is so important that the next lesson devotes a whole section to it. - Declaring variables without initialising them and then reading them. The compiler prevents it for local variables; be grateful.
- Overusing
var.var result = calculate();forces the reader to go and look up the method signature. Use it only when the type is obvious. - Tip: declare
finaleverything that is not going to change. It is free and it turns a potential bug into a compilation error. - Tip: use names that say what the variable holds, not what type it is.
daysLateis better thanintegerNumber1. - Tip: when in doubt about a
Stringmethod, open JShell and try it. Five seconds versus ten minutes of guessing.
Exercises
Exercise 1: Predict the output
Without running the code, write down what each line prints and justify why. Then check it in JShell or by compiling it.
public class TypeTest {
public static void main(String[] args) {
int a = 7;
int b = 2;
System.out.println(a / b);
System.out.println((double) a / b);
System.out.println((int) 3.99);
System.out.println(Math.round(3.99));
String title = "Effective Java";
title.toUpperCase();
System.out.println(title);
System.out.println(title.substring(0, 9));
System.out.println(title.length());
System.out.println("Total: " + 2 + 3);
System.out.println("Total: " + (2 + 3));
byte small = (byte) 300;
System.out.println(small);
}
}Exercise 2: A complete book card
Write the class FullCard that declares the variables needed for the book "Design Patterns" (ISBN 978-0000000002, year 1994, author "Erich Gamma et al.", available) and computes and displays:
- The book's age in years relative to 2026.
- The ISBN without the
978-prefix. - The title in uppercase.
- Whether the title is longer than 10 characters (use a
booleanvariable and compute the value with a comparison, withoutif).
Use final constants where appropriate and respect the naming conventions.
Exercise 3: Fixing the type errors
The following code has six compilation errors related to types. Find them, explain each one and write the corrected version.
public class TypeErrors {
public static void main(String[] args) {
float dailyRate = 0.25;
long identifier = 100000000045;
char section = "J";
int fine = 3.75;
final int LOAN_DAYS = 15;
LOAN_DAYS = 20;
int pages;
System.out.println(pages);
}
}Solutions
Solution 1
Line-by-line justification:
a / b→3. Both areint, so integer division happens: the result 3.5 is truncated to 3. It is Java's most classic gotcha.(double) a / b→3.5. The cast applies toabefore the division, so the operation is7.0 / 2and promotion gives3.5.(int) 3.99→3. The cast to an integer truncates the decimal part; it does not round.Math.round(3.99)→4. This one does round to the nearest integer.title→Effective Java.toUpperCase()returns a new string that is discarded, because it was not assigned.Strings are immutable.substring(0, 9)→Effective. From index 0 included up to 9 excluded: characters 0 through 8.length()→14. "Effective Java" has 9 + 1 space + 4 = 14 characters."Total: " + 2 + 3→Total: 23. It is evaluated left to right:"Total: " + 2gives"Total: 2", and the 3 is glued onto that string."Total: " + (2 + 3)→Total: 5. The parentheses force the numeric addition first.(byte) 300→44. Abyteonly reaches 127. The value overflows and only the low 8 bits of 300 are kept (100101100→00101100= 44). There is no warning at all: it is a silent loss.
Solution 2
public class FullCard {
public static void main(String[] args) {
// Constants: values that do not change during execution
final String COMPANY_NAME = "Nexus Software";
final int CURRENT_YEAR = 2026;
final int LONG_TITLE_LENGTH = 10;
final String ISBN_PREFIX = "978-";
// Book data
String title = "Design Patterns";
String author = "Erich Gamma et al.";
String isbn = "978-0000000002";
int publicationYear = 1994;
boolean available = true;
// 1. Age: integer subtraction
int age = CURRENT_YEAR - publicationYear;
// 2. ISBN without the prefix. ISBN_PREFIX.length() is 4, so
// substring(4) returns everything from the fifth character onwards.
String isbnWithoutPrefix = isbn.substring(ISBN_PREFIX.length());
// 3. Uppercase title. We store the result: Strings are immutable.
String uppercaseTitle = title.toUpperCase();
// 4. A comparison produces a boolean directly, with no need for an if.
boolean longTitle = title.length() > LONG_TITLE_LENGTH;
// --- Output ---
System.out.println("=== " + COMPANY_NAME + " - BiblioTech ===");
System.out.println("Title: " + title);
System.out.println("Author: " + author);
System.out.println("ISBN: " + isbn);
System.out.println("Published: " + publicationYear);
System.out.println("Available: " + available);
System.out.println("Age: " + age + " years");
System.out.println("ISBN without prefix: " + isbnWithoutPrefix);
System.out.println("Uppercase title: " + uppercaseTitle);
System.out.println("Long title: " + longTitle);
}
}Output:
=== Nexus Software - BiblioTech === Title: Design Patterns Author: Erich Gamma et al. ISBN: 978-0000000002 Published: 1994 Available: true Age: 32 years ISBN without prefix: 0000000002 Uppercase title: DESIGN PATTERNS Long title: true
The key idea in point 4: a comparison such as title.length() > 10 is a boolean expression. You do not need an if to obtain true or false; the if is for deciding what to do with that value, and that arrives in module 2.
Solution 3
The six errors:
float dailyRate = 0.25;— the literal0.25is adouble; it does not fit in afloatwithout a suffix. Fix:0.25f(or better, usedouble).long identifier = 100000000045;— the literal is read as anintand overflows its range. TheLsuffix is missing.char section = "J";— double quotes create aString. Acharneeds single quotes:'J'.int fine = 3.75;— assigning adoubleto anintis a narrowing conversion and requires an explicit cast (or, better, declaringfineas adouble, which is the right thing for money).LOAN_DAYS = 20;— the variable isfinal; it cannot be reassigned.System.out.println(pages);—pageshas been declared but never initialised, and local variables must have a value before being read.
Corrected version:
public class TypeErrors {
public static void main(String[] args) {
double dailyRate = 0.25; // 1. double is the natural type for decimals
long identifier = 100000000045L; // 2. L suffix for long literals
char section = 'J'; // 3. single quotes for char
double fine = 3.75; // 4. the amount is decimal, not integer
final int LOAN_DAYS = 15; // 5. constant: assigned only once
int pages = 416; // 6. initialised before being used
System.out.println("Daily rate: " + dailyRate);
System.out.println("Identifier: " + identifier);
System.out.println("Section: " + section);
System.out.println("Fine: " + fine);
System.out.println("Loan days: " + LOAN_DAYS);
System.out.println("Pages: " + pages);
}
}Conclusion
You now know how to declare, initialise and assign variables; you know the eight primitive types with their ranges and which ones you will really use; you write literals in any base and with the right suffixes; you tell primitives (which hold the value) apart from references (which hold an arrow into the heap); you have a grip on String, its immutability and its essential methods, including text blocks; you convert between types understanding when the conversion is automatic and when it truncates; you use wrappers and Integer.parseInt to turn text into numbers; you protect your business rules with final; and you know when var helps and when it gets in the way. With all of that you have modelled the first BiblioTech book.
In the next lesson, Operators, we will put that data in motion: arithmetic (including the integer-division trap and the modulo), compound assignment, increment and decrement, comparisons, logical operators with short-circuit evaluation, the ternary operator, bitwise operations, precedence, and the classic mistake of comparing strings with == instead of equals. The thread will be calculating the late fine for a BiblioTech loan.
Java Programming Course
Module 1: Introduction to Java
- Introduction to Java
- Setting Up the Development Environment
- Basic Syntax and Structure
- Variables and Data Types
- Operators
- Console Input and Output
- Your First Complete Program: BiblioTech
Module 2: Control Flow
- Conditional Statements
- Loops
- Switch Statements
- Break and Continue
- Debugging and Execution Traces
- Project: The BiblioTech Interactive Menu
Module 3: Object-Oriented Programming
- Introduction to OOP
- Classes and Objects
- Methods
- Constructors
- Inheritance
- Polymorphism
- Encapsulation
- Abstraction
- The Object Class: equals, hashCode and toString
Module 4: Advanced Object-Oriented Programming
- Interfaces
- Abstract Classes
- Inner Classes
- Anonymous Classes
- Lambda Expressions
- Functional Interfaces and Method References
- Enums and Records
Module 5: Data Structures and Collections
- Arrays
- The Collections Framework
- ArrayList
- LinkedList
- HashMap
- HashSet
- Queue and Deque
- Stack
- Sorting and Searching Collections
Module 6: Exception Handling
- Introduction to Exceptions
- The Try-Catch Block
- Throw and Throws
- Custom Exceptions
- The Finally Block
- Try-with-resources and AutoCloseable
- Error Handling Strategies and Logging
Module 7: File Input/Output
- Reading Files
- Writing Files
- File Streams
- BufferedReader and BufferedWriter
- Serialization
- The NIO.2 API: Path and Files
- Interchange Formats: CSV and Properties
Module 8: Multithreading and Concurrency
- Introduction to Multithreading
- Creating Threads
- Thread Lifecycle
- Synchronization
- Concurrency Utilities
- Concurrent Collections and Atomic Variables
- Asynchronous Tasks with CompletableFuture
Module 9: Networking
- Introduction to Networking
- Sockets
- ServerSocket
- DatagramSocket and DatagramPacket
- URL and HttpURLConnection
- The Modern HTTP Client
Module 10: Advanced Topics
- Generics
- Annotations
- Reflection
- Java 8 Features: Streams and Optional
- Dates and Times with java.time
- Java 9 and Beyond
- Memory, Garbage Collection and Performance
Module 11: Java Frameworks and Libraries
- Introduction to Java Frameworks
- Spring Framework
- Hibernate
- JUnit
- Maven
- Advanced Testing with Mockito
- Essential Ecosystem Libraries
