java-foundations Lesson 2 20 min read

Variables and Types

Strong typing — the contract between you and the compiler

Reading: Reges & Stepp: Ch. 2

After this lesson, you will be able to:

  • Declare variables with explicit types (int, double, String, boolean)
  • Explain why Java requires type declarations and how the compiler uses them
  • Use Scanner to read user input from the console
  • Perform arithmetic with integers and doubles, understanding integer division and casting
  • Convert between types using casting and String conversion methods

From Python’s Flexibility to Java’s Contracts

From CSCD 110: In Python, x = 5 works without declaring a type — Python figures it out at runtime. In Java, you must declare the type: int x = 5;. This is static typing — the compiler checks types before your program ever runs. More upfront work, but bugs are caught earlier.

In Python, you wrote:

age = 25
name = "Alice"
gpa = 3.7

Python figured out the types for you. In Java, you tell the compiler what type each variable holds:

int age = 25;
String name = "Alice";
double gpa = 3.7;

This is called static typing — every variable has a type that’s fixed at compile time. It’s more typing (literally), but the compiler now knows exactly what operations are valid. Try age + name and the compiler tells you immediately if that makes sense.


Primitive Types

Java has eight primitive types. You’ll use four constantly:

Type Size Range Example
int 4 bytes -2.1 billion to 2.1 billion int count = 42;
double 8 bytes ~15 decimal digits of precision double pi = 3.14159;
boolean 1 bit true or false boolean done = false;
char 2 bytes Single Unicode character char grade = 'A';

Plus byte, short, long, and float — you’ll encounter these less often.

Key difference from Python: Python has int with unlimited size and float. Java’s int overflows at ~2.1 billion, and double has finite precision. These limits matter in real programs.

Check Your Understanding
What happens if you write: int x = 3.7;
A x stores 3.7
B x stores 4 (rounded up)
C Compiler error — can't store a double in an int without casting
D x stores 3 (truncated automatically)
Answer: C. Java does not implicitly narrow types. A double literal like 3.7 cannot be assigned to an int variable without an explicit cast: int x = (int) 3.7; which truncates to 3.

Declaring vs. Assigning

Declaration creates the variable with its type. Assignment gives it a value. You can do both at once or separately:

// Declaration + assignment (most common)
int score = 100;

// Declaration first, assignment later
double temperature;
temperature = 98.6;

// Multiple declarations of the same type
int x = 0, y = 0, z = 0;

Common Pitfall: Using a variable before assigning it is a compiler error in Java. Python would give you a runtime NameError, but Java catches this at compile time.


Integer Division and Modulus

This catches every student at least once:

int a = 7;
int b = 2;
System.out.println(a / b);   // Prints 3, not 3.5!
System.out.println(a % b);   // Prints 1 (remainder)

When both operands are int, Java performs integer division — it truncates the decimal part. To get 3.5, at least one operand must be a double:

System.out.println(7.0 / 2);     // 3.5
System.out.println((double) 7 / 2);  // 3.5 — cast forces double division
Check Your Understanding
What does 15 / 4 evaluate to in Java?
A 3.75
B 3
C 4
D 3.0
Answer: B. Both operands are int, so Java performs integer division: 15 ÷ 4 = 3 remainder 3. The result is 3, not 3.75. Use 15.0 / 4 for decimal division.
int result = 5 / 2;
System.out.println(result);
double result = 5 / 2;
System.out.println(result);

Reading Input with Scanner

Java uses the Scanner class to read console input:

import java.util.Scanner;

public class TempConverter {
    public static void main(String[] args) {
        Scanner console = new Scanner(System.in);

        System.out.print("Enter temperature in Fahrenheit: ");
        double fahrenheit = console.nextDouble();

        double celsius = (fahrenheit - 32) * 5.0 / 9;
        System.out.println("Celsius: " + celsius);
    }
}
Scanner Method Reads Python Equivalent
nextInt() An integer int(input())
nextDouble() A decimal number float(input())
next() A single word input().split()[0]
nextLine() An entire line input()

Common Pitfall: Mixing nextInt() or nextDouble() with nextLine() leaves a stray newline in the buffer. Call console.nextLine() after nextInt() to consume it before reading a full line.


String Basics

String is not a primitive — it’s a class (notice the capital S). But you use it constantly:

String greeting = "Hello";
String name = "World";
String message = greeting + ", " + name + "!";  // Concatenation
System.out.println(message);  // Hello, World!

Useful String methods:

  • message.length() — character count
  • message.charAt(0) — first character ('H')
  • message.toUpperCase()"HELLO, WORLD!"
  • message.equals("Hello, World!") — content comparison (NOT ==)

Critical: Use .equals() to compare strings, never ==. The == operator compares references (memory addresses), not content. Two strings with identical text can be == false.

Check Your Understanding

Which of the following correctly declares a variable to store the value 3.14?


Summary

Java variables have fixed types declared at compile time. Primitives (int, double, boolean, char) store values directly. String is a class for text. Integer division truncates — cast to double when you need decimals. Use Scanner for input and .equals() to compare strings.