Learning Objectives

Understand Data Types

Learn Java's primitive and reference data types and their differences

Variable Declaration

Declare and initialize variables with proper naming conventions

Wrapper Classes

Use wrapper classes for primitive types in object contexts

Type Conversion

Master automatic and explicit type conversion and casting

Data Types in Java

Overview

Java has two main categories of data types: primitive types and reference types. Understanding the difference between these is crucial for writing efficient Java programs.

Primitive vs Reference Types

Primitive Types

  • Store actual values directly in memory
  • Fixed size (8 primitive types)
  • Stored on the stack
  • Cannot be null
  • Examples: int, double, boolean, char

Reference Types

  • Store references (memory addresses) to objects
  • Variable size (depends on the object)
  • Objects stored on the heap, references on stack
  • Can be null
  • Examples: String, Integer, Boolean, custom classes

Primitive Data Types

Java has 8 primitive data types that are built into the language. These are the fundamental building blocks for storing data in Java programs.

Primitive Data Types Reference

Data Type Size Range Default Value Example
byte 8 bits -128 to 127 0 byte age = 25;
short 16 bits -32,768 to 32,767 0 short year = 2024;
int 32 bits -2�� to 2��-1 0 int population = 1000000;
long 64 bits -26� to 26�-1 0L long worldPopulation = 8000000000L;
float 32 bits �3.4E-38 to �3.4E+38 0.0f float pi = 3.14f;
double 64 bits �1.7E-308 to �1.7E+308 0.0 double e = 2.718281828;
char 16 bits 0 to 65,535 '\u0000' char grade = 'A';
boolean 1 bit true or false false boolean isActive = true;

Reference Data Types

Reference types are objects that are instances of classes. They provide more functionality than primitive types and can be null.

Common Reference Types

Reference Type Description Example Notes
String Immutable sequence of characters String name = "John Doe"; Most commonly used reference type
Integer Wrapper class for int primitive Integer count = 42; Can be null, useful for collections
Boolean Wrapper class for boolean primitive Boolean isActive = true; Can be null, useful for nullable booleans
Double Wrapper class for double primitive Double price = 19.99; Can be null, useful for nullable doubles
Character Wrapper class for char primitive Character letter = 'A'; Can be null, useful for nullable chars
Custom Classes User-defined classes Person person = new Person(); Your own object types

Wrapper Classes

Wrapper classes provide object representations for primitive types. They're useful when you need:

  • Null values: Primitive types can't be null, but wrapper classes can
  • Collections: Many Java collections can only store objects, not primitives
  • Methods: Wrapper classes provide useful utility methods
// Primitive types
int primitiveInt = 42;
boolean primitiveBool = true;

// Wrapper classes
Integer wrapperInt = 42;        // Can be null
Boolean wrapperBool = true;     // Can be null

// Null values (only possible with wrappers)
Integer nullableInt = null;     // Valid
// int nullablePrimitive = null; // Compilation error!

// Collections require objects
ArrayList<Integer> numbers = new ArrayList<>(); // Works
// ArrayList<int> numbers = new ArrayList<>(); // Won't compile

Type Conversion & Casting

Overview

Type conversion in Java allows you to convert values from one data type to another. Java supports both automatic (implicit) and explicit (manual) type conversion.

Types of Conversion

Widening Conversion (Implicit)

Converting a smaller data type to a larger data type. This is safe and happens automatically.

// Widening conversions (automatic)
byte smallByte = 100;
short smallShort = smallByte;    // byte ? short
int smallInt = smallShort;       // short ? int
long smallLong = smallInt;       // int ? long
float smallFloat = smallLong;    // long ? float
double smallDouble = smallFloat; // float ? double

// char can also be widened
char charValue = 'A';
int charToInt = charValue;       // char ? int (gets ASCII value 65)
Widening Conversion Order
byte ? short ? int ? long ? float ? double
char ? int ? long ? float ? double

Narrowing Conversion (Explicit)

Converting a larger data type to a smaller data type. This requires explicit casting and may result in data loss.

// Narrowing conversions (explicit casting required)
double largeDouble = 123.456;
float largeFloat = (float) largeDouble;  // double ? float
long largeLong = (long) largeFloat;      // float ? long
int largeInt = (int) largeLong;          // long ? int
short largeShort = (short) largeInt;     // int ? short
byte largeByte = (byte) largeShort;      // short ? byte

// char narrowing
int intValue = 65;
char intToChar = (char) intValue;        // int ? char (gets 'A')
?? Data Loss Warning

Narrowing conversions can cause data loss:

int bigNumber = 1000000;
byte smallByte = (byte) bigNumber;  // Data loss! Result: -64

double preciseDouble = 3.14159;
int roundedInt = (int) preciseDouble;  // Decimal part lost! Result: 3
Why Data Loss Occurs:
int ? byte conversion:
  • int range: -2,147,483,648 to 2,147,483,647 (32 bits)
  • byte range: -128 to 127 (8 bits)
  • What happens: Only the lowest 8 bits are kept, higher bits are discarded
  • 1000000 in binary: 00000000 00001111 01000010 01000000
  • Kept bits: 11000000 (which is -64 in two's complement)
double ? int conversion:
  • double: Can store decimal numbers with high precision
  • int: Can only store whole numbers
  • What happens: The decimal part is truncated (not rounded)
  • 3.14159 ? 3: The .14159 part is completely lost
  • Note: Use Math.round() if you want proper rounding

Special Type Conversions

String Conversions

// Converting primitives to String
int number = 42;
String numberString = String.valueOf(number);  // "42"
String numberString2 = "" + number;            // "42" (concatenation)

// Converting String to primitives
String ageString = "25";
int age = Integer.parseInt(ageString);        // 25
double price = Double.parseDouble("19.99");   // 19.99
boolean isActive = Boolean.parseBoolean("true"); // true

// Wrapper class conversions
Integer wrapperInt = Integer.valueOf("100");  // Integer object
Double wrapperDouble = Double.valueOf("3.14"); // Double object

Wrapper Class Conversions

// Primitive to Wrapper (autoboxing)
int primitiveInt = 42;
Integer wrapperInt = primitiveInt;  // Automatic conversion

// Wrapper to Primitive (unboxing)
Integer wrapperInteger = 100;
int primitiveInteger = wrapperInteger;  // Automatic conversion

// Manual conversions
int manualInt = wrapperInteger.intValue();
double manualDouble = wrapperInteger.doubleValue();
String manualString = wrapperInteger.toString();

Best Practices & Common Pitfalls

Safe Conversions

  • Use widening conversions when possible
  • Check ranges before narrowing conversions
  • Use wrapper classes for nullable values

Avoid These

  • Don't cast without understanding data loss
  • Avoid casting between unrelated types
  • Be careful with floating-point precision
// Good: Check range before casting
int largeNumber = 1000000;
if (largeNumber >= Byte.MIN_VALUE && largeNumber <= Byte.MAX_VALUE) {
    byte safeByte = (byte) largeNumber;
} else {
    System.out.println("Number too large for byte!");
}

// Good: Use appropriate types
double price = 19.99;
int roundedPrice = (int) Math.round(price);  // 20 (proper rounding)

Variables & Constants

Variable Declaration

Basic Declaration

// Declaration only
int age;
String name;

// Declaration with initialization
int age = 25;
String name = "John Doe";

// Multiple variables of same type
int x, y, z;
int a = 1, b = 2, c = 3;

Variable Naming Rules

Must start with

Letter, underscore, or dollar sign

Can contain

Letters, digits, underscores, dollar signs

Cannot use

Java keywords

Case sensitive

age and Age are different variables

Constants

Using final Keyword

// Constants (similar to C's const)
final double PI = 3.14159;
final int MAX_STUDENTS = 100;
final String COMPANY_NAME = "TechCorp";

// Attempting to change a constant will cause compilation error
// PI = 3.14; // This will not compile
Constant Naming Convention
  • UPPER_SNAKE_CASE: All caps with underscores
  • Examples: MAX_SIZE, DEFAULT_TIMEOUT, PI

Practical Examples

Temperature Converter

public class TemperatureConverter {
    public static void main(String[] args) {
        // Declare variables
        double celsius = 25.0;
        double fahrenheit, kelvin;
        
        // Constants
        final double C_TO_F_FACTOR = 9.0 / 5.0;
        final double C_TO_F_OFFSET = 32.0;
        final double C_TO_K_OFFSET = 273.15;
        
        // Calculations
        fahrenheit = celsius * C_TO_F_FACTOR + C_TO_F_OFFSET;
        kelvin = celsius + C_TO_K_OFFSET;
        
        // Display results
        System.out.printf("Celsius:     %.1f�C%n", celsius);
        System.out.printf("Fahrenheit:  %.1f�F%n", fahrenheit);
        System.out.printf("Kelvin:      %.2fK%n", kelvin);
    }
}

Student Information System

public class StudentInfo {
    public static void main(String[] args) {
        // Primitive types
        int studentId = 1001;
        double gpa = 3.85;
        boolean isActive = true;
        char grade = 'A';
        
        // Reference types
        String studentName = "Alice Johnson";
        String email = "alice.johnson@university.edu";
        Integer age = 20;  // Wrapper class - can be null
        Boolean hasScholarship = true;  // Wrapper class - can be null
        
        // Display student information
        System.out.println("Student Information:");
        System.out.println("ID: " + studentId);
        System.out.println("Name: " + studentName);
        System.out.println("Email: " + email);
        System.out.println("Age: " + age);
        System.out.println("GPA: " + gpa);
        System.out.println("Grade: " + grade);
        System.out.println("Active: " + isActive);
        System.out.println("Scholarship: " + hasScholarship);
        
        // Demonstrating null values with wrapper classes
        age = null;  // Valid with Integer
        hasScholarship = null;  // Valid with Boolean
        // studentId = null;  // This would cause compilation error with int
        
        System.out.println("\nAfter update:");
        System.out.println("Age: " + age);
        System.out.println("Scholarship: " + hasScholarship);
    }
}

Key Points: This example shows how primitive types (int, double, boolean, char) and reference types (String, Integer, Boolean) work together. Notice how wrapper classes like Integer and Boolean can be null, while primitive types cannot.

Type Conversion Examples

public class TypeConversionDemo {
    public static void main(String[] args) {
        System.out.println("=== Type Conversion Examples ===\n");
        
        // 1. Widening Conversions (Automatic)
        System.out.println("1. Widening Conversions (Automatic):");
        byte smallByte = 100;
        int widenedInt = smallByte;  // byte ? int
        System.out.println("byte " + smallByte + " ? int " + widenedInt);
        
        char charValue = 'A';
        int charToInt = charValue;   // char ? int
        System.out.println("char '" + charValue + "' ? int " + charToInt + " (ASCII)");
        
        // 2. Narrowing Conversions (Explicit Casting)
        System.out.println("\n2. Narrowing Conversions (Explicit):");
        double largeDouble = 123.456;
        int narrowedInt = (int) largeDouble;  // double ? int
        System.out.println("double " + largeDouble + " ? int " + narrowedInt + " (decimal lost)");
        
        int bigNumber = 1000;
        byte smallByte2 = (byte) bigNumber;  // int ? byte
        System.out.println("int " + bigNumber + " ? byte " + smallByte2 + " (data loss!)");
        
        // 3. String Conversions
        System.out.println("\n3. String Conversions:");
        int number = 42;
        String numberString = String.valueOf(number);
        System.out.println("int " + number + " ? String \"" + numberString + "\"");
        
        String ageString = "25";
        int age = Integer.parseInt(ageString);
        System.out.println("String \"" + ageString + "\" ? int " + age);
        
        // 4. Wrapper Class Conversions
        System.out.println("\n4. Wrapper Class Conversions:");
        Integer wrapperInt = 100;
        int primitiveInt = wrapperInt;  // Autounboxing
        System.out.println("Integer " + wrapperInt + " ? int " + primitiveInt);
        
        int newInt = 200;
        Integer newWrapper = newInt;    // Autoboxing
        System.out.println("int " + newInt + " ? Integer " + newWrapper);
        
        // 5. Safe Conversion with Range Checking
        System.out.println("\n5. Safe Conversion with Range Checking:");
        int testNumber = 500;
        if (testNumber >= Byte.MIN_VALUE && testNumber <= Byte.MAX_VALUE) {
            byte safeByte = (byte) testNumber;
            System.out.println("Safe conversion: int " + testNumber + " ? byte " + safeByte);
        } else {
            System.out.println("int " + testNumber + " is outside byte range!");
        }
    }
}

Key Points: This example demonstrates various type conversions including widening (automatic), narrowing (explicit casting), String conversions, wrapper class autoboxing/unboxing, and safe conversion practices with range checking.

Playing with Local Variables

public class VariablePlayground {
    public static void main(String[] args) {
        // Declaring and initializing different types of variables
        String name = "Alice";
        int age = 25;
        double height = 1.75;
        boolean isStudent = true;
        char grade = 'A';
        
        // Displaying the variables
        System.out.println("=== Variable Information ===");
        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
        System.out.println("Height: " + height + " meters");
        System.out.println("Is Student: " + isStudent);
        System.out.println("Grade: " + grade);
        
        // Playing with variable operations
        System.out.println("\n=== Variable Operations ===");
        
        // String concatenation
        String greeting = "Hello, " + name + "!";
        System.out.println(greeting);
        
        // Mathematical operations
        int birthYear = 2024 - age;
        System.out.println("Birth year: " + birthYear);
        
        // Type conversion and calculations
        double heightInCm = height * 100;
        System.out.println("Height in centimeters: " + heightInCm);
        
        // Boolean operations
        boolean canVote = age >= 18;
        System.out.println("Can vote: " + canVote);
        
        // Character operations
        char nextGrade = (char)(grade + 1);
        System.out.println("Next grade: " + nextGrade);
        
        // Variable reassignment
        System.out.println("\n=== Variable Reassignment ===");
        age = 26;  // Updating age
        System.out.println("Updated age: " + age);
        
        // Using variables in expressions
        double bmi = 65.0 / (height * height);  // Assuming weight is 65kg
        System.out.println("BMI: " + bmi);
        
        // Final output
        System.out.println("\n=== Summary ===");
        System.out.println(name + " is " + age + " years old, " + height + "m tall, and is a student: " + isStudent);
    }
}

Key Points: This example demonstrates local variable declaration, initialization, and manipulation including different data types, string concatenation, mathematical operations, type conversion, boolean expressions, and variable reassignment.

Complete Example with Input/Output

import java.util.Scanner;

public class FirstProgram {
    public static void main(String[] args) {
        // Display welcome message
        System.out.println("Welcome to Java Programming!");
        System.out.println("=============================");
        
        // Get user input
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("Enter your name: ");
        String name = scanner.nextLine();
        
        System.out.print("Enter your favorite number: ");
        int favoriteNumber = scanner.nextInt();
        
        // Process and display results
        // Note: The + operator is used for string concatenation (joining strings together)
        System.out.println("\nHello, " + name + "!");
        System.out.println("Your favorite number is: " + favoriteNumber);
        System.out.println("Twice your favorite number is: " + (favoriteNumber * 2));
        
        // Close scanner
        scanner.close();
        
        System.out.println("\nThank you for using this program!");
    }
}

Key Points: This example shows how to create an interactive program using Scanner for input/output operations, demonstrating string concatenation, mathematical operations, and proper resource management by closing the scanner.

Working with Instance Variables

public class SimpleStudent {
    // Instance variables - belong to the object
    String name;
    int age;
    String major;
    
    // Constructor - initializes the instance variables
    public SimpleStudent(String name, int age, String major) {
        this.name = name;
        this.age = age;
        this.major = major;
    }
    
    public static void main(String[] args) {
        // Create two student objects
        SimpleStudent student1 = new SimpleStudent("Alice", 20, "Computer Science");
        SimpleStudent student2 = new SimpleStudent("Bob", 22, "Mathematics");
        
        // Access instance variables directly
        System.out.println("Student 1:");
        System.out.println("Name: " + student1.name);
        System.out.println("Age: " + student1.age);
        System.out.println("Major: " + student1.major);
        
        System.out.println("\nStudent 2:");
        System.out.println("Name: " + student2.name);
        System.out.println("Age: " + student2.age);
        System.out.println("Major: " + student2.major);
        
        // Update instance variable
        System.out.println("\n--- Updating Age ---");
        student1.age = 21;
        System.out.println("Updated age for " + student1.name + ": " + student1.age);
    }
}

Key Points: This example demonstrates instance variables (class-level variables), constructors for initialization, object creation, direct access to instance variables, and updating instance variable values.

Summary

Primitive Data Types

Learned Java's 8 primitive data types and their characteristics

Reference Types

Understood reference data types and their differences from primitives

Wrapper Classes

Mastered wrapper classes for primitive types in object contexts

Type Conversion

Learned automatic and explicit type conversion and casting

Variable Declaration

Declared and initialized variables with proper naming conventions

Safe Practices

Applied safe conversion practices and avoided common pitfalls

Next Steps

  1. Complete the exercises in the exercises.md file
  2. Practice declaring variables of different types
  3. Move to Module 3: Control Structures

Key Terms

Primitive Types

Basic data types built into Java (int, double, boolean, char, etc.)

Reference Types

Object types that store references to objects in memory

Wrapper Classes

Object representations of primitive types (Integer, Double, Boolean, etc.)

Type Conversion

Converting values from one data type to another

Autoboxing

Automatic conversion from primitive to wrapper class

Unboxing

Automatic conversion from wrapper class to primitive

?? Module 2 Complete!

You now have a solid foundation in Java data types and variables. Time to learn about control structures!