แต่ละ primitive type ใน Java มี built-in wrapper class ตรงกัน และ wrapper classes เหล่านี้เป็น immutable เช่น Integer, Float, Double, Byte เป็นต้น เหตุผลหลักของการใช้ wrappers: เข้าถึง type information ของ primitive type, Auto-Boxing feature (primitive ถูก promote เป็น object reference อัตโนมัติ), และเคลื่อนย้าย primitive data ใน data structures
สร้าง instance ของ Wrapper Classes ได้ด้วย new operator หรือใช้เมธอด valueOf() เช่น Integer.valueOf() เมธอดนี้จะ reuse existing Integer objects ที่มีค่าเดียวกันบน heap ถ้ามี object ค่าเดียวกันอยู่แล้ว จะคืน reference ไป object เดิม มิฉะนั้นสร้างใหม่
Snippet 1: Object Creation และ Comparison
jshell> Integer int1 = new Integer(10);
int1 ==> 10
jshell> Integer int2 = new Integer(10);
int2 ==> 10
jshell> Integer int3 = Integer.valueOf(10);
int3 ==> 10
jshell> Integer int4 = Integer.valueOf(10);
int4 ==> 10
jshell> int1 == int2;
$7 ==> true
jshell> int3 == int4;
$8 ==> true
หมายเหตุ: ผลลัพธ์ true สำหรับ int3 == int4 เพราะ valueOf() cache ค่า -128 ถึง 127 แต่ new Integer() สร้าง object ใหม่ทุกครั้ง int1 == int2 เป็น true ใน JShell อาจเป็นเพราะ optimization ของ JShell environment
Snippet 2: Auto-boxing และ Constants
jshell> Integer abc1 = Integer.valueOf(700);
abc1 ==> 700
jshell> Integer abc2 = 700; // auto-boxing
abc2 ==> 700
jshell> Integer abc3 = 700; // auto-boxing
abc3 ==> 700
jshell> abc2 == abc3
$4 ==> false // ค่า 700 ไม่อยู่ใน cache range (-128 to 127)
jshell> Integer.MAX_VALUE
$5 ==> 2147483647
jshell> Integer.MIN_VALUE
$6 ==> -2147483648
jshell> Integer.SIZE
$7 ==> 32
jshell> Integer.BYTES
$8 ==> 4
Wrapper Classes และ Primitive Types
| Primitive | Wrapper Class | Cache Range |
|---|---|---|
| boolean | Boolean | TRUE, FALSE (2 instances) |
| byte | Byte | -128 to 127 |
| short | Short | -128 to 127 |
| int | Integer | -128 to 127 |
| long | Long | -128 to 127 |
| float | Float | ไม่มี cache |
| double | Double | ไม่มี cache |
| char | Character | 0 to 127 (\u0000 to \u007F) |
Best Practices
- ใช้
valueOf()แทนnew Wrapper()- ประหยัด memory, เร็วกว่า - หลีกเลี่ยง
==สำหรับ wrapper comparison - ใช้.equals() - Auto-boxing/unboxing มี overhead - หลีกเลี่ยงใน loop ที่ critical
- ใช้ primitive types เมื่อเป็นไปได้สำหรับ performance
- ระวัง NullPointerException จาก unboxing null wrapper
เมธอดสำคัญของ Integer
Integer.parseInt("123") // String -> int
Integer.valueOf(123) // int -> Integer (cached)
Integer.toString(123) // int -> String
Integer.toBinaryString(10) // "1010"
Integer.toHexString(255) // "ff"
Integer.compare(5, 10) // -1
Integer.sum(5, 10) // 15
Integer.max(5, 10) // 10