Data Types

From MediaWiki
Revision as of 14:27, 20 October 2025 by Bfh-sts (talk | contribs) (Created page with "= Java Data Type Categories = Java groups data into two families: '''primitive types''' (hold simple values) and '''reference types''' (hold references to objects on the heap). Unlike Python’s dynamic typing, Java is '''statically typed''': every variable has a declared type, checked at compile time. If you’ve used Go, that idea will feel familiar. == Quick map (what to reach for) == * Whole numbers: int (default) → long for timestamps/big ranges * Real numbers: d...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Java Data Type Categories

Java groups data into two families: primitive types (hold simple values) and reference types (hold references to objects on the heap). Unlike Python’s dynamic typing, Java is statically typed: every variable has a declared type, checked at compile time. If you’ve used Go, that idea will feel familiar.

Quick map (what to reach for)

  • Whole numbers: int (default) → long for timestamps/big ranges
  • Real numbers: double (default) → float if you really need to save memory
  • True/false: boolean
  • Single code unit: char (UTF-16 code unit)
  • Text: String
  • Fixed-size collections: arrays (int[], String[])
  • Resizable collections: List, Map, Set (from java.util)
  • Exact money/precision math: BigDecimal (reference type)

Primitive Data Types

Primitives are not objects and have no methods. They’re stored directly in variables (no reference indirection) and are fast.

Type Bits (fixed) Range / Values Default (for fields) Typical use
boolean JVM-defined (1 bit conceptually) true / false false flags, conditions
char 16 U+0000 … U+FFFF (UTF-16 code unit) U+0000 single code unit (be careful with full Unicode)
byte 8 −128 … 127 0 raw bytes, I/O, buffers
short 16 −32 768 … 32 767 0 niche numeric needs
int 32 −2^31 … 2^31−1 0 default whole number
long 64 −2^63 … 2^63−1 0L timestamps, counters
float 32 IEEE-754 single precision 0.0f big numeric arrays where memory matters
double 64 IEEE-754 double precision 0.0d default real number

Note: Boolean (uppercase B) is the wrapper class for primitive boolean.

Literals and readability

  • Decimal, hex (0x2A), binary (0b101010), octal (052).
  • Underscores for readability: 1_000_000.
  • Suffixes: L for long (42L), f/F for float (3.0f). Double is default for floating-point.
  • Char literals: 'A', 'λ'.

Numeric promotions and casting (core rules)

  • Widening (safe, automatic): byte → short → int → long → float → double; and char → int → …
  • Narrowing (explicit, may lose data): (byte) someInt, (int) someLong, etc.
  • Binary numeric promotion: in + − * / %, byte/short/char become int; mixing with long/float/double promotes to the wider type.
  • Integer division truncates: 5 / 2 is 2. Use 5 / 2.0 for 2.5.
  • Overflow on integers wraps (no exception). For checked arithmetic, use Math.addExact, subtractExact, multiplyExact.

boolean (from easy to advanced)

  • Values: true or false. Default for fields: false.
  • Operators: && (and), || (or), ! (not). They short-circuit (right side may not run).
  • No implicit numeric conversion (you can’t add true to a number).
  • Advanced: in streams, filter predicates are boolean-valued lambdas.
boolean ok = (3 < 5) && !false; // true
if (ok) { System.out.println("go"); }

char (UTF-16 code unit)

  • 16-bit unsigned code unit. Some Unicode characters need two char values (surrogate pair).
  • Arithmetic with char promotes to int.
  • For full Unicode correctness (emoji, many scripts), iterate by code points, not char.
// Basic char
char letter = 'A';
int code = letter; // 65

// Safer iteration over a String's Unicode code points
String s = "A😊Z";
s.codePoints().forEach(cp -> System.out.println(cp)); // prints code points as ints

byte, short, int, long (integers)

  • All are signed, two’s complement.
  • Division by zero throws ArithmeticException.
  • Remainder has the same sign as the dividend.
  • Bitwise ops: & (and), | (or), ^ (xor), ~ (not), << (left shift), >> (signed right shift), >>> (unsigned right shift).
  • Unsigned helpers:
 * Byte.toUnsignedInt, Short.toUnsignedInt
 * Integer.compareUnsigned, divideUnsigned, toUnsignedString
 * Long.compareUnsigned, divideUnsigned, toUnsignedString
// Literals and underscores
int mask = 0b1010_1100; // 172
long nanos = 12_345_678_901L;

// Shifts and masks
int flags = 0;
flags |= (1 << 2);       // set bit 2
boolean hasBit2 = (flags & (1 << 2)) != 0;

// Checked arithmetic
int a = Integer.MAX_VALUE;
try {
  int b = Math.addExact(a, 1); // throws ArithmeticException
} catch (ArithmeticException ex) {
  System.out.println("overflow");
}

float, double (floating point)

  • IEEE-754. Special values exist: NaN, positive/negative infinity, negative zero.
  • Comparisons with NaN are always false (except Double.isNaN(x)).
  • Decimal fractions like 0.1 are approximations in binary. For money, use BigDecimal.
  • Rounding: Math.round, floor, ceil.
double x = 0.1 + 0.2;         // 0.30000000000000004
System.out.println(x == 0.3); // false
System.out.println(Double.isNaN(Math.sqrt(-1))); // true

Wrapper classes and autoboxing

Wrappers make primitives usable where objects are required (collections, generics). Autoboxing/unboxing converts between them automatically.

Mapping: boolean↔Boolean, char↔Character, byte↔Byte, short↔Short, int↔Integer, long↔Long, float↔Float, double↔Double

Caveats:

  • Unboxing null throws NullPointerException.
  • Equality: use equals(...) for wrappers; == compares identity.
  • Small values may be cached (commonly −128..127 for Integer/Long). Do not rely on ==.
Integer i = 128;   // autoboxed
Integer j = 128;   // a different object in general
System.out.println(i.equals(j)); // true
System.out.println(i == j);      // often false

List<Integer> nums = new java.util.ArrayList<>();
nums.add(42);     // autoboxed int → Integer
int v = nums.get(0); // unboxed

Reference (Non-Primitive) Types

These store references (addresses) to objects on the heap. All reference types ultimately inherit from java.lang.Object.

String (immutable, pooled)

  • Immutable: operations create new strings.
  • Literals may be interned (shared) by the VM.
  • Compare content with equals(...). Use == only to test identity (same object).
  • Efficient building: StringBuilder for many concatenations (StringBuffer is synchronized; rarely needed).

Useful APIs:

  • length, charAt, substring, indexOf, startsWith, endsWith, replace, split, join, format, repeat
  • bytes/encoding: getBytes(StandardCharsets.UTF_8)
String a = "Hello";
String b = "He" + "llo";           // often same interned object as a
System.out.println(a.equals(b));   // true

// Avoid repeated concatenation in loops; use StringBuilder
StringBuilder sb = new StringBuilder();
for (int k = 0; k < 3; k++) sb.append("Hi ");
System.out.println(sb.toString()); // "Hi Hi Hi "

Arrays (objects with length, fixed size)

  • Homogeneous, zero-indexed, fixed length.
  • Default initialization: numbers→0, boolean→false, references→null.
  • Multidimensional arrays are arrays of arrays (jagged shapes allowed).
  • Equality is by identity; use Arrays.equals / Arrays.deepEquals for content.
  • Utilities in java.util.Arrays: sort, binarySearch, copyOf, fill, toString, deepToString
// 1D and 2D arrays
int[] a = {10, 20, 30};
System.out.println(a.length);       // 3

int[][] grid = new int[2][];
grid[0] = new int[] {1, 2};
grid[1] = new int[] {3, 4, 5};      // jagged

// Content equality
int[] x = {1,2,3}, y = {1,2,3};
System.out.println(java.util.Arrays.equals(x, y)); // true

Classes, interfaces, and Object basics

  • Your own types are classes and interfaces. Single inheritance for classes; multiple inheritance via interfaces.
  • Key Object methods: toString, equals, hashCode.
  • Contract: if you override equals, also override hashCode.
class Point {
  final int x, y;
  Point(int x, int y) { this.x = x; this.y = y; }

  @Override public boolean equals(Object o) {
    if (!(o instanceof Point p)) return false;
    return x == p.x && y == p.y;
  }
  @Override public int hashCode() { return java.util.Objects.hash(x, y); }
  @Override public String toString() { return "Point(" + x + "," + y + ")"; }
}

Enums (type-safe constants)

  • Define a fixed set of values with optional fields/behavior.
  • Great for states, categories, days, etc.
enum Traffic { RED, YELLOW, GREEN }
Traffic t = Traffic.RED;
switch (t) {
  case RED -> System.out.println("stop");
  case GREEN -> System.out.println("go");
  default -> System.out.println("wait");
}

Records (concise immutable data carriers, Java 16+)

  • Auto-generated equals, hashCode, toString; fields are final.
public record User(String name, int age) {}
User u = new User("Ada", 37);
System.out.println(u.name()); // accessor

Optional (avoid null for “maybe” values)

  • Wrap a possibly-present value; encourage explicit handling.
java.util.Optional<String> maybe = java.util.Optional.of("hi");
String result = maybe.map(s -> s + "!").orElse("empty");

BigInteger and BigDecimal (arbitrary precision)

  • Immutable big number classes.
  • For money, construct BigDecimal from String to avoid binary rounding surprises.
import java.math.BigDecimal;
import java.math.MathContext;

BigDecimal price = new BigDecimal("19.99");
BigDecimal tax = price.multiply(new BigDecimal("0.0775"), MathContext.DECIMAL64);
BigDecimal total = price.add(tax);

Type inference (var)

  • Since Java 10: var for local variables with obvious initializers.
  • Still statically typed; the compiler infers the concrete type.
  • Not allowed for fields, parameters, or returns.
var list = new java.util.ArrayList<String>(); // inferred as ArrayList<String>
list.add("BFH");

Equality, identity, and null

  • Primitives compare by value with ==.
  • Objects: == checks identity (same reference), equals checks content.
  • null means “no object”. Dereferencing null throws NullPointerException.
  • For safe use, validate inputs, consider Optional, and leverage Objects.requireNonNull.

Control-flow with booleans (short-circuiting)

String s = null;
if (s != null && s.length() > 0) {
  // length() evaluated only if s != null
}

Bits and bytes (advanced)

  • Right shift >> keeps sign; >>> fills with zeros.
  • Masking, packing, and unpacking are common when handling protocols/files.
// Pack RGBA bytes into an int
int r=10, g=20, b=30, a=255;
int packed = (r & 0xFF) << 24 | (g & 0xFF) << 16 | (b & 0xFF) << 8 | (a & 0xFF);

// Extract
int r2 = (packed >>> 24) & 0xFF;

Exceptions to watch for

  • ArithmeticException: integer divide by zero, checked arithmetic methods
  • ArrayIndexOutOfBoundsException: bad index
  • NullPointerException: dereferencing null
  • NumberFormatException: parsing a bad number string

Parsing and formatting numbers

int n = Integer.parseInt("42");
double d = Double.parseDouble("3.14");
String s1 = String.format("n=%d, d=%.2f", n, d);

Putting it all together (tiny program)

import java.util.*;
import java.math.*;

public class TypesTour {
  public static void main(String[] args) {
    // primitives and promotion
    int n = 5;
    double avg = (n + 2) / 2.0;  // 3.5
    boolean ok = n > 3;

    // strings
    String msg = "Count: " + n + ", ok=" + ok;

    // arrays
    int[] data = new int[3]; // {0,0,0}
    data[0] = 42;

    // collections (need wrappers)
    List<Integer> numbers = new ArrayList<>();
    numbers.add(10); numbers.add(20);

    // equality examples
    String a = "Hi", b = new String("Hi");
    System.out.println(a.equals(b)); // true

    // floating point caveat
    System.out.println(0.1 + 0.2);   // slightly off 0.3

    // money with BigDecimal
    BigDecimal price = new BigDecimal("19.99");
    BigDecimal tax = price.multiply(new BigDecimal("0.08"));
    System.out.println("Total: " + price.add(tax));

    System.out.println(msg + " data0=" + data[0] + " size=" + numbers.size());
  }
}

Cheat sheet: when to pick what

  • int: default whole numbers. long for time in milliseconds or large counts.
  • double: default real numbers; float if memory matters and small precision loss is ok.
  • boolean: flags and conditions.
  • char: single UTF-16 code unit (be careful with full Unicode).
  • String: text; use equals for comparison; use StringBuilder for many appends.
  • Arrays for fixed size; List/Map/Set for flexible collections.
  • BigDecimal for money and precision-critical calculations.