AP Computer Science A • Using Objects and Methods

Variables and Data Types

Understanding how Java stores, categorizes, and manipulates data through its strongly typed variable system.

AP Computer Science A illustration with code, binary digits, and programming braces
Inside this lesson 10 sections 5 questions 8 figures

SECTION 1

Historical Context & Motivation

Every program, from a simple calculator to a sophisticated web application, must store and manipulate data. In the earliest days of computing, programmers worked directly with raw memory addresses and binary values, a process that was both error-prone and extraordinarily tedious. The concept of a variable—a named container for a piece of data—emerged as one of the most transformative abstractions in programming language design, allowing humans to reason about data symbolically rather than numerically. Coupled with data types, which classify what kind of data a variable holds and what operations are legal on that data, these concepts form the bedrock upon which all Java programs are built.

1957 • FORTRAN Introduces Named Variables

IBM's FORTRAN compiler allowed programmers to use symbolic names like X and TOTAL instead of raw memory addresses, pioneering the variable concept still used today.

1970 • Pascal Popularizes Strong Typing

Niklaus Wirth's Pascal enforced strict type declarations for every variable, demonstrating that compile-time type checking could catch entire categories of bugs before execution.

1983 • C++ Brings Object Types

Bjarne Stroustrup extended C with class-based types, establishing the distinction between primitive values and object references that Java would later refine.

1995 • Java Defines Its Type System

James Gosling and Sun Microsystems released Java with exactly eight primitive types, reference types for objects, and platform-independent data sizes—guaranteeing that an int is always 32 bits, regardless of the hardware.

Java's decision to be a statically typed language means that every variable must be declared with a specific type before it can be used, and the compiler enforces type rules at compile time rather than at runtime. This design raises an essential question: how does Java's type system classify data, and how do the rules governing primitive types differ from those governing reference types? Mastering this distinction is not merely academic—it is the foundation for understanding parameter passing, method return values, and the behavior of objects throughout the AP Computer Science A curriculum.

SECTION 2

Core Principles & Definitions

Before writing any Java code, you need a precise vocabulary for the concepts that govern how data is declared, stored, and accessed. Java organizes its entire type system around a fundamental split: primitive types store actual values directly in memory, while reference types store addresses (references) that point to objects located elsewhere in memory. Understanding this distinction is essential for predicting how assignment, comparison, and method calls behave.

1

Variable Declaration

A statement that specifies a variable's type and name, such as int score;. The compiler reserves the appropriate amount of memory and enforces that only compatible values can be stored.
2

Initialization

Assigning a variable its first value, such as int score = 95;. Local variables in Java must be initialized before use; the compiler will reject code that reads an uninitialized local variable.
3

Primitive Types

Java's eight built-in types (int, double, boolean, etc.) that store values directly. The AP exam focuses on int, double, and boolean.
4

Reference Types

Any type that refers to an object, including String, arrays, and all user-defined classes. A reference variable holds the memory address of the object, not the object itself.
5

Type Casting

Converting a value from one type to another. Java performs widening casts (e.g., int → double) automatically but requires explicit narrowing casts (e.g., (int) 3.7) that may lose data.
✦

KEY TAKEAWAY

Think of a variable as a labeled mailbox. The type determines the size and shape of the mailbox—an int mailbox holds a single whole number, while a reference-type mailbox holds a slip of paper with a forwarding address to a larger package (the object) stored in a warehouse (the heap). Assigning one reference variable to another copies only the forwarding slip, not the package, which is why two reference variables can point to the exact same object.

SECTION 3

Visual Explanation — Primitive vs. Reference Memory Model

Primitive vs. Reference Variables in MemorySTACK (Variable Storage)HEAP (Object Storage)int agevalue: 1717double gpavalue: 3.853.85boolean passedvalue: truetrueString nameref: 0x7F2A0x7F2AString Object @ 0x7F2A"Alice"String greetingref: 0x3B100x3B10String Object @ 0x3B10"Hello, world!"
The three primitive variables (age, gpa, passed) hold their values directly on the stack. The two reference variables (name, greeting) store memory addresses that point to String objects stored on the heap.

The diagram above illustrates the fundamental memory distinction that the AP exam frequently tests. When you declare int age = 17;, the value 17 is stored directly in the variable's memory slot on the stack. In contrast, when you write String name = "Alice";, the variable name does not contain the characters "Alice"—instead, it holds a reference (essentially a memory address) that points to a String object on the heap. This is why comparing two String variables with == checks whether they point to the same object, not whether they contain the same sequence of characters—a nuance that the .equals() method resolves.

Two collaborators adjust one blue articulated model while a second model stands apart.Java assignment copies a value. For primitive variables this is the primitive value; for object variables it is a reference to an object.

Primitive variables x and y separate after reassignment; String references a and b point to different immutable strings.After x is changed to 9, y keeps its copied value of 42. For String variables, assignment copies a reference: reassigning a to "world" leaves b referring to the unchanged "hello" object.

SECTION 4

How It Works — Declaration, Assignment, and Casting

Variable Declaration and Assignment Syntax

In Java, every variable declaration follows the pattern type variableName = value;. The compiler uses the declared type to determine how many bytes to allocate and what operations are permissible. Declaration and initialization can occur on the same line, or the variable can be declared first and assigned later, though local variables must be initialized before they are read.

DECLARATION SYNTAX

typevariableName=expression;type variableName = expression;

Where type is any primitive or reference type, variableName follows camelCase naming conventions, and expression evaluates to a compatible type.

Integer Division and Truncation

One of the most common pitfalls on the AP exam involves integer division. When both operands of the division operator are int values, Java performs integer division, which truncates the decimal portion rather than rounding. For example, 7 / 2 evaluates to 3, not 3.5. If at least one operand is a double, the result is a double: 7.0 / 2 yields 3.5.

INTEGER DIVISION RULE

int/int→int(truncatedtowardzero)int / int → int (truncated toward zero)

To force floating-point division, cast one operand: (double) a / b. The modulus operator % returns the remainder: 7 % 2 evaluates to 1.

Widening and Narrowing Casts

Java automatically performs widening conversions that preserve information, such as promoting an int to a double when necessary. However, a narrowing conversion—converting a double to an int—requires an explicit cast because the fractional part is discarded. Writing int x = (int) 9.99; assigns 9 to x—the decimal portion is truncated, not rounded.

CASTING SYNTAX

(targetType)expression(targetType) expression

Examples: (int) 3.14 → 3, (double) 5 → 5.0. Casting truncates toward zero for conversions from floating-point to integer.

SECTION 5

Detailed Breakdown — AP-Testable Data Types

While Java defines eight primitive types in total, the AP Computer Science A exam focuses on three primitives and several reference types. The table below provides a comprehensive breakdown of each type's characteristics, range, and common usage patterns that you should commit to memory for both the multiple-choice and free-response sections of the exam.

TypeCategorySizeRange / DetailsExample
intPrimitive32 bits−2,147,483,648 to 2,147,483,647int count = 42;
doublePrimitive64 bits≈ ±1.8 × 10³⁰⁸; ~15 decimal digits of precisiondouble pi = 3.14159;
booleanPrimitive1 bit (logical)true or false onlyboolean done = false;
StringReferenceVariesImmutable sequence of characters; compare with .equals()String s = "Hi";
Class typesReferenceVariesAny user-defined or library class; default value is nullScanner sc = new Scanner(System.in);

AP-testable data types with their categories, sizes, and usage

Java Type System HierarchyJava Data TypesPrimitive TypesReference Typesint32-bit integerStores: valuesdouble64-bit floatingStores: valuesbooleantrue / falseStores: valuesStringImmutable textStores: refsArraysFixed-sizeStores: refsClassesUser-definedStores: refsPrimitive Behavior• Stored directly on the stack• Compared with == (checks values)• Default: 0 (int), 0.0 (double), falseReference Behavior• Reference on stack, object on heap• == checks address, .equals() checks content• Default: null (for instance variables)
Java's type system hierarchy showing the three AP-testable primitive types (int, double, boolean) and the main reference type categories. Note the key behavioral differences summarized at the bottom.

Notice that the hierarchy diagram emphasizes a critical behavioral difference: primitive variables store their actual values, so the == operator compares values directly. Reference variables store addresses, so == compares whether two variables point to the same object in memory—not whether the objects are logically equivalent. This distinction is the single most common source of bugs tested on the AP exam, particularly with String comparisons.

SECTION 6

Worked Example — Tracing Variable State

The following example walks through a realistic code segment, tracing the values of variables after each statement. This type of code-tracing exercise appears frequently on the AP exam's multiple-choice section, where you must mentally execute Java statements and predict output.

Tracing Assignments, Casting, and Integer Division

  1. 1

    Step 1 — Declare and Initialize Variables

    Consider the following code segment: int a = 17; int b = 5; double c = 2.5; After these statements, a holds 17, b holds 5, and c holds 2.5.
    a = 17, b = 5, c = 2.5
  2. 2

    Step 2 — Perform Integer Division

    int d = a / b; Since both a and b are int values, Java performs integer division: 17 / 5 = 3 with remainder 2. The fractional part is truncated.
    d = 3 (not 3.4)
  3. 3

    Step 3 — Compute Modulus

    int e = a % b; The modulus operator returns the remainder of integer division: 17 % 5 = 2 because 17 = 3 × 5 + 2.
    e = 2
  4. 4

    Step 4 — Mixed-Type Arithmetic with Widening

    double f = a + c; The int value a (17) is automatically widened to 17.0 before addition. The result is 17.0 + 2.5 = 19.5, stored as a double.
    f = 19.5
  5. 5

    Step 5 — Explicit Narrowing Cast

    int g = (int) f; The explicit cast (int) truncates the decimal portion of 19.5, yielding 19. Without the cast, this line would cause a compile error because a double cannot be implicitly narrowed to an int.
    g = 19
  6. 6

    Step 6 — Casting Before Division

    double h = (double) a / b; The cast applies to a first, converting it to 17.0. Now the division is 17.0 / 5, which is floating-point division, yielding 3.4. Compare this to Step 2, where the same operands produced 3.
    h = 3.4

SECTION 7

Primitive vs. Reference — A Side-by-Side Comparison

Many AP exam questions hinge on the behavioral differences between primitive and reference types—particularly in the context of assignment, comparison, and method parameter passing. The following table consolidates these differences into a single reference that clarifies common misconceptions.

CharacteristicPrimitive TypesReference Types
What is storedThe actual value (e.g., 42, 3.14, true)A memory address pointing to the object on the heap
== operatorCompares values — 5 == 5 is trueCompares addresses — two objects with identical content may return false
Content comparisonUse == (it already compares values)Use .equals() method
Assignment (=)Copies the value — changes to one copy don't affect the otherCopies the reference — both variables now point to the same object
Default value0 (int), 0.0 (double), false (boolean) for instance variablesnull for instance variables
Method parametersPass by value — the method receives a copy; the original is unaffectedPass by value of the reference — the method can modify the object's state via the copied reference

Behavioral comparison of primitive and reference types

✦

KEY TAKEAWAY

In engineering, a blueprint reference number and the physical building are two very different things. If you copy the reference number to a second ledger, both ledgers now refer to the same building—changes to the building are visible from both. Similarly, when you assign one reference variable to another in Java, both variables point to the same object, and mutations through either variable are reflected everywhere. With primitives, each variable is its own independent copy, like having two separate physical houses that happen to look alike.

SECTION 8

Connection to Advanced Topics

The concepts of variables and data types are not isolated topics—they form the foundation for nearly every advanced topic in the AP Computer Science A curriculum. Understanding how data is stored, typed, and passed informs your reasoning about object-oriented design, polymorphism, and algorithm analysis. The table below maps each core concept from this lesson to its downstream applications.

Foundation ConceptAdvanced ApplicationWhy It Matters
Primitive vs. referenceAutoboxing (Integer, Double)ArrayList cannot hold primitives; Java automatically wraps int → Integer
Reference assignmentAliasing and mutabilityTwo references to the same ArrayList mean changes through one appear in the other
Type declarationsPolymorphism and inheritanceA variable declared as a superclass type can hold a subclass object at runtime
Integer divisionArray index calculationsBinary search uses integer division to find midpoints; truncation behavior is critical
Type castingDowncasting in inheritanceCasting an Object to a specific class type requires explicit syntax and may throw ClassCastException

How foundational variable concepts connect to advanced AP CSA topics

As you progress through the course, you will encounter these concepts repeatedly. The distinction between storing values versus storing references resurfaces in every discussion of arrays, ArrayLists, and object interactions. Mastering variables and data types now provides the mental model you need to reason confidently about more complex constructs like inheritance hierarchies, interface implementations, and recursive data structures.

💡

Looking Ahead

The next unit will build directly on reference types by exploring how to create objects using constructors, invoke instance methods, and use the String and Math classes. Every method call, parameter, and return value you encounter will reinforce the primitive-vs-reference distinction you have learned here.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

Consider the following code segment: String s1 = "hello"; String s2 = s1; String s3 = new String("hello"); Which of the following correctly describes the result of evaluating s1 == s2 and s1 == s3?
  • A. s1 == s2 is true and s1 == s3 is true
  • B. s1 == s2 is true and s1 == s3 is false
  • C. s1 == s2 is false and s1 == s3 is false
  • D. s1 == s2 is false and s1 == s3 is true
Show answer (B)
B is correct. The assignment s2 = s1 copies the reference stored in s1 to s2, so both point to the exact same String object in the string pool; therefore s1 == s2 is true. However, new String("hello") explicitly creates a new String object on the heap, so s3 points to a different object even though the content is identical. Since == compares references (addresses), not content, s1 == s3 is false. Option A is wrong because new forces a distinct object. Option C is wrong because s1 and s2 do share the same reference. Option D reverses the correct outcomes.

Question 2: BASIC CALCULATION

What is the output of the following code segment? int x = 23; int y = 7; System.out.println(x / y + " r " + x % y);
  • A. 3.285714 r 2
  • B. 3 r 2
  • C. 3.0 r 2.0
  • D. 4 r 2
Show answer (B)
B is correct. Since x and y are both int, 23 / 7 performs integer division yielding 3 (truncated, not rounded), and 23 % 7 yields the remainder 2. The string concatenation produces "3 r 2". Option A is wrong because integer division does not produce a decimal result. Option C is wrong because the operands are int, not double. Option D is wrong because integer division truncates toward zero, not rounds up.

Question 3: INTERMEDIATE

Consider the following code segment: double a = 11; int b = 4; int c = (int) (a / b) + a / (double) b; What happens when this code is compiled?
  • A. The code compiles and c is assigned the value 4
  • B. The code compiles and c is assigned the value 5
  • C. The code compiles and c is assigned the value 5.75
  • D. The code does not compile because of a type mismatch
Show answer (D)
D is correct. Let's trace the expression. First, a / b is 11.0 / 4 = 2.75 (since a is a double). The cast (int) (a / b) truncates this to 2. Second, a / (double) b is 11.0 / 4.0 = 2.75. Adding these gives 2 + 2.75 = 4.75, which is a double. The result cannot be stored in int c without an explicit narrowing cast, so the compiler reports an error: possible lossy conversion from double to int. Options A and B are wrong because the code never compiles. Option C is wrong for the same reason, and also misidentifies the type of c as capable of holding a double value.

Question 4: APPLIED

3 pts
A student is writing a method to convert a temperature from Fahrenheit to Celsius. The formula is C = 5/9 × (F − 32). The student writes: public static double toCelsius(int fahrenheit) { double celsius = 5 / 9 * (fahrenheit - 32); return celsius; } The method compiles but returns incorrect values. Explain why the method produces wrong results and provide a corrected version of the calculation line. Your corrected code must use casting or a double literal to fix the bug.
Show answer
Rubric (3 points): Point 1 — Identify the bug: The expression 5 / 9 performs integer division because both 5 and 9 are int literals. Integer division truncates, so 5 / 9 evaluates to 0, causing the entire expression to evaluate to 0 regardless of the fahrenheit value. Point 2 — Explain the fix: At least one operand of the division must be a double so that floating-point division is performed. This can be accomplished by using a double literal (5.0 or 9.0) or by casting one operand, e.g., (double) 5 / 9. Point 3 — Provide correct code: Any of the following are acceptable: double celsius = 5.0 / 9 * (fahrenheit - 32); double celsius = (double) 5 / 9 * (fahrenheit - 32); double celsius = 5 / 9.0 * (fahrenheit - 32); All three ensure that 5/9 evaluates to approximately 0.5556 rather than 0.

Question 5: CRITICAL THINKING

4 pts
Write a complete Java method public static String describeChange(double oldPrice, double newPrice) that computes the percent change from oldPrice to newPrice, truncates it to a whole number using a cast, and returns a String of the form "Change: X%" where X is the truncated integer percent change. For example, if oldPrice is 80.0 and newPrice is 95.0, the percent change is 18.75, which truncates to 18, and the method returns "Change: 18%". The formula for percent change is ((newPrice − oldPrice) / oldPrice) × 100.
Show answer
Rubric (4 points): Point 1 — Correct method signature: Method is declared with the correct return type (String), correct parameter types (both double), and is public static. Point 2 — Correct percent change calculation: Computes (newPrice - oldPrice) / oldPrice * 100 using double arithmetic (since both parameters are double, this happens automatically). The expression correctly evaluates to a floating-point percent change value. Point 3 — Correct use of casting to truncate: Uses (int) cast to convert the double percent change to a truncated integer value. Must cast the full expression, not just one operand. Point 4 — Correct String construction and return: Uses string concatenation to build and return a String in the exact format "Change: X%". Sample Solution: public static String describeChange(double oldPrice, double newPrice) { double change = (newPrice - oldPrice) / oldPrice * 100; int truncated = (int) change; return "Change: " + truncated + "%"; } For oldPrice = 80.0 and newPrice = 95.0: change = (95.0 − 80.0) / 80.0 × 100 = 18.75. Casting to int truncates to 18. The method returns "Change: 18%".

SUMMARY

Variables and Data Types — Summary

Summary

Java's type system divides all data into two fundamental categories. Primitive types (int, double, and boolean for the AP exam) store values directly on the stack and are compared using ==. Reference types (such as String and all class types) store memory addresses that point to objects on the heap and should be compared using the .equals() method for content equality.

Every variable must be declared with a type before use, and Java's static typing catches type mismatches at compile time. Integer division truncates toward zero when both operands are int, widening conversions happen automatically (int → double), and narrowing casts require explicit syntax and truncate the fractional part. These principles underpin every subsequent topic in AP Computer Science A, from method calls and parameter passing to arrays, ArrayLists, and inheritance.

Varsity Tutors • AP Computer Science A • Variables and Data Types