Quiz 2

Data Types & Operators in Java

2531 words
13 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# Data Types & Operators in Java ## 🎯 Learning Objectives By the end of this topic, you will be able to: - Distinguish between primitive types (int, double, char, boolean) and reference types - Declare, initialize, and use variables of all primitive types - Perform type casting (widening and narrowing) safely - Use...

Data Types & Operators in Java

🎯 Learning Objectives

By the end of this topic, you will be able to:
  • Distinguish between primitive types (int, double, char, boolean) and reference types
  • Declare, initialize, and use variables of all primitive types
  • Perform type casting (widening and narrowing) safely
  • Use arithmetic, relational, logical, assignment, and bitwise operators
  • Understand overflow, underflow, and precision issues

📋 Prerequisites

  • Java Introduction (week01/01-java-introduction.md): Compilation, JVM, Hello World
  • BSCS1002 — Python: You've used variables and operators in Python; Java is more explicit about types

1. Intuition: Why Do We Need Types?

1.1 What Problem Does This Solve?

Imagine a warehouse where boxes of different sizes hold different kinds of items: small boxes for screws (4 bytes), medium boxes for books (8 bytes), and large crates for furniture (any size). If you know the box size, you know exactly how many shelves (memory slots) to allocate. In Python, you don't declare types — a variable can hold a number, then a string, then a list. The interpreter figures it out at runtime. Java is different: you must declare the type of every variable before using it. This is called static typing.
Why it matters: Static typing catches type errors at compile-time, not runtime. If you try to store "hello" in an int variable, javac refuses to compile. This eliminates entire categories of bugs before the program even runs.

1.2 Mental Model: Variables as Labeled Boxes

Every variable in Java is a labeled box of a fixed size and shape:
java
int age = 25;
    ↓
┌────────────────┐
│ age             │  ← label (variable name)
├────────────────┤
│      25         │  ← value (stored in memory)
└────────────────┘
  Size: 4 bytes
  Shape: can only hold integers
You cannot put a "different-shaped" value (like 3.14 or "hello") into this box — the compiler prevents it.

2. Primitive Types — The Building Blocks

Java has exactly 8 primitive types. They are not objects — they hold raw values directly in memory.

2.1 The Eight Primitive Types

TypeSizeRangeDefaultExampleUse Case
byte1 byte-128 to 1270byte b = 100;Saving memory in large arrays
short2 bytes-32,768 to 32,7670short s = 10000;Saving memory when range fits
int4 bytes-2³¹ to 2³¹−10int i = 42;Default integer type
long8 bytes-2⁶³ to 2⁶³−10Llong l = 100L;Large numbers (timestamps, IDs)
float4 bytes±3.4×10⁻³⁸ to ±3.4×10³⁸0.0ffloat f = 3.14f;Scientific calculations (memory-saving)
double8 bytes±1.7×10⁻³⁰⁸ to ±1.7×10³⁰⁸0.0ddouble d = 3.14159;Default decimal type
char2 bytes0 to 65,535 (Unicode)'\u0000'char c = 'A';Single Unicode characters
booleanJVM-dependenttrue or falsefalseboolean b = true;Logical conditions

2.2 Important Details

Integer Literals:
java
int decimal = 42;        // Decimal (base 10)
int hex = 0x2A;          // Hexadecimal (base 16) — starts with 0x
int binary = 0b101010;   // Binary (base 2) — starts with 0b
int octal = 052;         // Octal (base 8) — starts with 0 (avoid confusion!)
int big = 1_000_000;     // Underscores for readability (Java 7+)
Floating-Point Literals:
java
double d1 = 3.14;        // double by default
double d2 = 3.14d;       // explicit d suffix
float f1 = 3.14f;        // f suffix REQUIRED for float
double sci = 1.23e-4;    // Scientific notation: 0.000123
Common Mistake: float f = 3.14; fails because 3.14 is a double literal. Always add f suffix for floats. Character Literals:
java
char letter = 'A';       // Single quotes, NOT double
char digit = '9';        // Character 9, not integer 9
char newline = '\n';     // Escape sequence
char unicode = '\u0041'; // Unicode escape — same as 'A'

3. Reference Types — Objects That Live on the Heap

3.1 Primitive vs Reference

AspectPrimitiveReference
StoresThe actual valueA memory address (pointer) to an object
WhereStack (local variables)Stack → Heap (the object)
Default0, 0.0, false, '\u0000'null (no object)
MethodsCannot call methodsCan call object methods
Equality== compares values== compares references (not content!)

3.2 Memory Model

java
int x = 10;           // x on stack, value=10
String s = "Hello";   // s on stack → points to "Hello" on heap
(Diagram)

3.3 The Special String Type

String is a reference type, but Java treats it specially:
java
String s1 = "Hello";         // String literal (stored in string pool)
String s2 = "Hello";         // Reuses same object from pool
String s3 = new String("Hello"); // Forces new object on heap
System.out.println(s1 == s2);      // true — same reference
System.out.println(s1 == s3);      // false — different references
System.out.println(s1.equals(s3)); // true — same content
Key Insight: Always use .equals() to compare String content. The == operator only compares references (memory addresses), not the text inside.

4. Type Casting — Converting Between Types

4.1 Widening (Implicit) Casting

Java automatically converts a smaller type to a larger type when no data is lost:
java
int myInt = 100;
long myLong = myInt;      // OK: int → long (widening)
double myDouble = myInt;  // OK: int → double (widening)
byte b = 50;
int i = b;                // OK: byte → int (widening)
Widening order: byte → short → int → long → float → double (The chain also includes char → int)

4.2 Narrowing (Explicit) Casting

When converting a larger type to a smaller type, you must explicitly cast — data may be lost:
java
double pi = 3.14159;
int truncated = (int) pi;  // Explicit cast: double → int
System.out.println(truncated); // 3 (fractional part lost!)
long big = 1_000_000_000_000L;
int small = (int) big;
System.out.println(small); // Unpredictable — overflow!

4.3 Overflow Examples

java
int max = Integer.MAX_VALUE;   // 2,147,483,647
int overflow = max + 1;
System.out.println(overflow);  // -2,147,483,648 (wraps around!)
int underflow = Integer.MIN_VALUE - 1;
System.out.println(underflow); // 2,147,483,647 (wraps around!)
(Diagram)

5. Operators in Java

5.1 Arithmetic Operators

OperatorMeaningExampleResult
+Addition5 + 38
-Subtraction5 - 32
*Multiplication5 * 315
/Division5 / 22 (integer!)
/Division (double)5.0 / 22.5
%Modulus (remainder)5 % 21

5.2 Integer Division Trap — Common Mistake

java
int a = 5;
int b = 2;
double result = a / b;      // result = 2.0, NOT 2.5!
// Because a/b is integer division first (5/2=2), then promoted to double
double correct = (double) a / b;  // result = 2.5

5.3 Relational Operators

OperatorMeaningExampleResult
==Equal to5 == 3false
!=Not equal to5 != 3true
>Greater than5 > 3true
<Less than5 < 3false
>=Greater or equal5 >= 3true
<=Less or equal5 <= 3false

5.4 Logical Operators

OperatorMeaningShort-circuit?Example
&&ANDYes(x > 0) && (x < 100)
``OR
!NOTN/A!isEmpty
&AND (non-short-circuit)No(x > 0) & (x < 100)
``OR (non-short-circuit)No
^XORNo(x > 0) ^ (x < 0)
Short-circuit means: If the left side of && is false, the right side is never evaluated. Similarly for ||: if left is true, right is skipped.
java
String s = null;
if (s != null && s.length() > 0) {  // SAFE: short-circuit prevents null pointer
    System.out.println("Not empty");
}
if (s != null & s.length() > 0) {   // UNSAFE: & evaluates both sides — NullPointerException!
    System.out.println("Not empty");
}

5.5 Assignment Operators

OperatorExampleEquivalent to
=x = 5x = 5
+=x += 3x = x + 3
-=x -= 3x = x - 3
*=x *= 3x = x * 3
/=x /= 3x = x / 3
%=x %= 3x = x % 3

5.6 Increment/Decrement Operators

OperatorNameExampleEffect
++xPre-incrementint y = ++x;Increment x, then assign to y
x++Post-incrementint y = x++;Assign x to y, then increment x
--xPre-decrementint y = --x;Decrement x, then assign to y
x--Post-decrementint y = x--;Assign x to y, then decrement x
java
int x = 5;
int y = ++x;    // x=6, y=6 (increment first)
int z = x++;    // x=7, z=6 (assign first, increment after)

5.7 Bitwise Operators

OperatorMeaningExample
&Bitwise AND5 & 31 (0101 & 0011 = 0001)
``Bitwise OR
^Bitwise XOR5 ^ 36 (0101 ^ 0011 = 0110)
~Bitwise complement~5-6 (inverts all bits)
<<Left shift5 << 110 (multiply by 2)
>>Right shift (signed)5 >> 12 (divide by 2)
>>>Right shift (unsigned)-5 >>> 12147483645

6. Java vs Python: Types & Operators

FeatureJavaPython
Type declarationRequired: int x = 5;Optional (dynamic): x = 5
Type checkingStatic (compile-time)Dynamic (runtime)
Primitive types8 fixed-size primitivesEverything is an object (even ints)
Type conversionExplicit narrowing cast requiredImplicit widening, but may raise exceptions
Incrementx++, ++x, x--, --xNot available (x += 1 only)
Ternaryx > 0 ? "pos" : "neg"Same syntax "pos" if x > 0 else "neg"
String comparisons1.equals(s2) for contents1 == s2 compares content (strings are interned)

7. Common Pitfalls

Pitfall 1: Integer Division

java
double result = 5 / 2;  // result = 2.0, not 2.5!
Why: Both operands are int, so / performs integer division (truncates). The result 2 is then promoted to 2.0. Fix: Make at least one operand a double: 5.0 / 2 or (double)5 / 2.

Pitfall 2: Comparing Strings with ==

java
String s1 = "Hello";
String s2 = new String("Hello");
System.out.println(s1 == s2);  // false!
Why: == compares references (memory addresses), not content. s1 and s2 point to different objects. Fix: Use s1.equals(s2) for content comparison.

Pitfall 3: Float Without f Suffix

java
float f = 3.14;  // Compile error!
Why: 3.14 is a double literal. You can't store a double in a float without explicit casting. Fix: float f = 3.14f; or float f = (float) 3.14;

Pitfall 4: Overflow Without Warning

java
int population = 9_000_000_000;  // Compile error (too large for int)
Fix: Use long and L suffix: long population = 9_000_000_000L;

Pitfall 5: Uninitialized Local Variables

java
int x;
System.out.println(x);  // Compile error!
Why: Local variables in Java are NOT given default values. The compiler forces you to initialize them. Fix: int x = 0; before using it.

8. Practice Questions

Q1: What is the output of this code?
java
int a = 10;
double b = 3.5;
int c = a + (int) b;
System.out.println(c);
Answer: 13
Reasoning:
  1. (int) b casts 3.5 to 3 (truncation, not rounding)
  2. a + 3 = 10 + 3 = 13
  3. Result stored in int c, prints 13 Q2: What is the output?
java
int x = 5;
int y = x++ * 2;
System.out.println(x + ", " + y);
Answer: 6, 10
Reasoning:
  1. x++ is post-increment: uses current value 5, then increments x to 6
  2. y = 5 * 2 = 10
  3. After the line, x = 6, y = 10 Q3: Explain the output
java
System.out.println(10 / 3);
System.out.println(10.0 / 3);
System.out.println(10 / 3.0);
Answer:
pseudo
3
3.3333333333333335
3.3333333333333335
  1. 10 / 3: Both operands are int → integer division → 3
  2. 10.0 / 3: One operand is double → floating-point division → 3.333...
  3. 10 / 3.0: Same as above → 3.333... Q4: What is the value of result?
java
boolean result = (10 > 5) && (5 < 2) || (3 == 3);
Answer: true
Reasoning:
  1. (10 > 5) = true
  2. (5 < 2) = false
  3. true && false = false
  4. (3 == 3) = true
  5. false || true = true
Operator precedence: && has higher precedence than ||, so (true && false) || true = false || true = true. Q5: Why does this code fail to compile?
java
public class Test {
    public static void main(String[] args) {
        int x;
        if (args.length > 0) {
            x = Integer.parseInt(args[0]);
        }
        System.out.println(x);
    }
}
Answer: Compilation error: "variable x might not have been initialized."
The compiler sees that x is only assigned inside the if block, which may not execute. Java requires all local variables to be definitely assigned before use. Fix by giving x a default value: int x = 0; Q6: What happens if you cast a large long to int?
java
long big = 1_000_000_000_000L;
int small = (int) big;
System.out.println(small);
Answer: The output is -727379968 (or some unexpected number).
Reasoning: long value 1,000,000,000,000 in binary is larger than the 32 bits an int can hold. The cast truncates to the lower 32 bits, which may result in a completely different value (including negative). There is no exception — Java silently truncates. Q7: What is the output?
java
System.out.println(5 & 3);
System.out.println(5 | 3);
System.out.println(5 ^ 3);
System.out.println(5 << 1);
Answer:
pseudo
1
7
6
10
Reasoning:
  • 5 = 0101, 3 = 0011
  • 0101 & 0011 = 0001 = 1
  • 0101 | 0011 = 0111 = 7
  • 0101 ^ 0011 = 0110 = 6
  • 5 << 1 = 1010 = 10 (multiply by 2) Q8: What is the difference between && and & in Java?
Answer:
  • && is short-circuit AND: if the left operand is false, the right operand is NOT evaluated
  • & is non-short-circuit AND: both operands are always evaluated
Example:
java
String s = null;
if (s != null && s.length() > 0) { }  // Safe — short-circuit prevents NPE
if (s != null & s.length() > 0) { }   // Throws NullPointerException!
Q9: What is the range of a byte and why does Java use it?
Answer: A byte stores values from -128 to 127 (inclusive), using 1 byte (8 bits) of memory. It's used when:
  1. Working with raw binary data (file I/O, network protocols)
  2. Saving memory in large arrays (e.g., byte[] vs int[] saves 75% memory)
  3. Interacting with systems that use 8-bit data
Range calculation: 2⁸ = 256 possible values. Since Java uses two's complement for negatives: -128 to 127. Q10: What are the default values for primitives in Java?
Answer (applies to fields, NOT local variables):
  • byte, short, int: 0
  • long: 0L
  • float: 0.0f
  • double: 0.0d
  • char: '\u0000' (null character)
  • boolean: false
  • Any reference type: null
Local variables do NOT get default values — they must be explicitly initialized before use.

📐 Key Formulas / Concepts

ConceptSyntaxExample
Widening conversionAutomaticint → long
Narrowing conversionExplicit (type)(int) 3.14
Integer division/ with two ints5/2 = 2
Modulus%5%2 = 1
Post-incrementx++Uses then increments
Pre-increment++xIncrements then uses
Short-circuit AND&&Right side skipped if left false
Short-circuit OR||Right side skipped if left true

🔗 Cross-References

Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.