Lesson Completion
Back to course

Type Conversion and Casting: Converting Between Data Types

Beginner
10 minutes4.8Java

1. The Hook (The "Byte-Sized" Intro)

  • In a Nutshell: Widening (automatic): Small → large type (byte →int → long → float → double), no data loss.
  • Narrowing (explicit cast): Large → small type, requires (type)value, may lose data! Type promotion: In expressions, smaller types promote to int (byte + byte → int).
  • String conversion: Integer.parseInt("123") (String → int), String.valueOf(123) (int → String).
  • Overflow: Exceeding range wraps around (127 + 1 = -128 for byte).
  • Golden rule: Auto-widen, manually narrow. Always check for data loss when narrowing!

Think of pouring water. Widening = small cup → large bucket (no spill). Narrowing = large bucket → small cup (overflow!). Cast = carefully pour to avoid spill. Type promotion = measuring cups auto-convert to standard size. Overflow = water loops back!


2. Conceptual Clarity (The "Simple" Tier)

💡 The Analogy

  • Widening: Upgrade (economy → business class, always OK)
  • Narrowing: Downgrade (requires confirmation, may lose perks)
  • Overflow: Odometer rolling over (999,999 → 000,000)
  • Type Promotion: Auto-format (handwriting → typed)

3. Technical Mastery (The "Deep Dive")

java
// =========================================== // 1. WIDENING (Implicit/Automatic) // =========================================== // byte → short → int → long → float → double // Smaller type automatically converts to larger byte b = 10; short s = b; // ✅ byte → short (automatic) int i = s; // ✅ short → int (automatic) long l = i; // ✅ int → long (automatic) float f = l; // ✅ long → float (automatic) double d = f; // ✅ float → double (automatic) // Direct conversions int num = 100; long bigNum = num; // ✅ Automatic double decimal = num; // ✅ Automatic (100.0) // No data loss byte small = 42; int large = small; // ✅ 42 fits perfectly // =========================================== // 2. NARROWING (Explicit/Manual Cast) // =========================================== // Requires explicit cast: (targetType)value // ⚠️ MAY LOSE DATA! double d = 9.99; int i = (int)d; // ✅ Explicit cast (i = 9, loses .99!) long l = 1000L; int i = (int)l; // ✅ Explicit cast float f = 3.14f; byte b = (byte)f; // ✅ Explicit cast (b = 3) // ❌ Without cast double price = 19.99; int dollars = price; // ❌ Compile error! Narrowing requires cast // ✅ With cast int dollars = (int)price; // ✅ dollars = 19 (truncates decimal!) // =========================================== // 3. DATA LOSS IN NARROWING // =========================================== // ⚠️ Decimal truncation (not rounding!) double value = 9.99; int truncated = (int)value; // 9 (not 10!) double negative = -5.7; int result = (int)negative; // -5 (truncates toward zero) // ⚠️ Overflow (value too large) int large = 130; byte small = (byte)large; // -126 (overflow!) // Why? byte range: -128 to 127 // 130 wraps around: 130 - 256 = -126 int huge = 1000; byte tiny = (byte)huge; // -24 (overflow!) // =========================================== // 4. TYPE PROMOTION IN EXPRESSIONS // =========================================== // In expressions, smaller types (byte, short, char) promote to int byte b1 = 10; byte b2 = 20; byte b3 = b1 + b2; // ❌ Compile error! // Why? b1 + b2 promotes to int! // ✅ Fix 1: Use int int result = b1 + b2; // ✅ result = 30 // ✅ Fix 2: Cast back to byte byte b3 = (byte)(b1 + b2); // ✅ b3 = 30 // char promotion char c1 = 'A'; // 65 char c2 = 'B'; // 66 int sum = c1 + c2; // 131 (65 + 66) // Promotion hierarchy in expressions byte + byteint short + shortint byte + intint int + longlong long + floatfloat float + doubledouble // =========================================== // 5. STRING TO PRIMITIVE CONVERSION // =========================================== // String → primitive (parse methods) String strNum = "123"; int num = Integer.parseInt(strNum); // 123 String strDouble = "3.14"; double d = Double.parseDouble(strDouble); // 3.14 String strBool = "true"; boolean b = Boolean.parseBoolean(strBool); // true // Other parse methods byte b = Byte.parseByte("10"); short s = Short.parseShort("100"); long l = Long.parseLong("1000"); float f = Float.parseFloat("3.14"); // ⚠️ NumberFormatException for invalid input try { int invalid = Integer.parseInt("abc"); // ❌ Throws exception! } catch (NumberFormatException e) { System.out.println("Invalid number format"); } // =========================================== // 6. PRIMITIVE TO STRING CONVERSION // =========================================== // Method 1: String.valueOf() int num = 123; String str1 = String.valueOf(num); // "123" double d = 3.14; String str2 = String.valueOf(d); // "3.14" boolean b = true; String str3 = String.valueOf(b); // "true" // Method 2: Concatenation (simpler but less clear) String str4 = num + ""; // "123" String str5 = "" + d; // "3.14" // Method 3: Wrapper toString() String str6 = Integer.toString(num); // "123" String str7 = Double.toString(d); // "3.14" // =========================================== // 7. WRAPPER CLASS CONVERSION (Autoboxing) // =========================================== // Primitive → Wrapper (autoboxing) int primitive = 10; Integer wrapper = primitive; // ✅ Auto-boxing // Wrapper → Primitive (unboxing) Integer wrapperObj = 20; int primitiveValue = wrapperObj; // ✅ Auto-unboxing // Manual boxing/unboxing (old way) Integer manualBox = Integer.valueOf(30); int manualUnbox = manualBox.intValue(); // ⚠️ NullPointerException risk Integer nullWrapper = null; int value = nullWrapper; // ❌ NullPointerException! // =========================================== // 8. OVERFLOW DEMONSTRATION // =========================================== // byte overflow example byte max = 127; byte overflow = (byte)(max + 1); // -128 (wraps around!) System.out.println(max); // 127 System.out.println(overflow); // -128 // int overflow int maxInt = Integer.MAX_VALUE; // 2,147,483,647 int overflowInt = maxInt + 1; // -2,147,483,648 (wraps!) // Preventing overflow (use long) long safe = (long)maxInt + 1; // 2,147,483,648 (correct!)

5. The Comparison & Decision Layer

ConversionTypeSyntaxData Loss?
WideningAutomaticlong l = 10;No
NarrowingManual castint i = (int)10L;Yes (possible)
String → intParseInteger.parseInt("10")Exception if invalid
int → StringvalueOfString.valueOf(10)No

6. The "Interview Corner" (The Edge)

The "Killer" Interview Question: "Why does byte + byte result in int?" Answer: Type promotion! In expressions, types smaller than int (byte, short, char) are automatically promoted to int.

java
byte b1 = 10; byte b2 = 20; byte b3 = b1 + b2; // ❌ Compile error! // b1 + b2 promotes to int (not byte!) // ✅ Fix 1: Store in int int result = b1 + b2; // ✅ // ✅ Fix 2: Cast back to byte byte b3 = (byte)(b1 + b2); // ✅

Follow-up: "What happens when you cast 130 to byte?" Answer: Overflow! 130 becomes -126.

java
int large = 130; byte small = (byte)large; // -126 // Calculation: 130 - 256 = -126 // byte range: -128 to 127 // Values wrap around like odometer

Pro-Tips:

  1. Check range before narrowing:
java
int value = 1000; if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) { byte b = (byte)value; // Safe } else { System.out.println("Value out of range!"); }
  1. Use Math.toIntExact() to detect overflow:
java
long bigValue = 10_000_000_000L; try { int i = Math.toIntExact(bigValue); // Throws if overflow } catch (ArithmeticException e) { System.out.println("Overflow detected!"); }

Topics Covered

Java FundamentalsJava Syntax

Tags

#java#basics#syntax#variables#data-types#beginner-friendly

Last Updated

2025-02-01