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 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: 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
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