在 Java 中,包装类(如 Integer
、Long
、Character
等)为了提高性能和节省内存,对一定范围内的值进行了缓存。这种缓存机制使得在某些情况下,相同的值会返回相同的对象,而不是创建新的对象。
1. 包装类的缓存机制
2. 示例:Integer
的缓存机制
代码示例:
java">public class IntegerCacheExample {public static void main(String[] args) {Integer a = 127; // 使用缓存Integer b = 127; // 使用缓存System.out.println(a == b); // trueInteger c = 128; // 超出缓存范围,创建新对象Integer d = 128; // 超出缓存范围,创建新对象System.out.println(c == d); // false}
}
输出:
true
false
3. 修改 Integer
的缓存范围
运行命令:
java -XX:AutoBoxCacheMax=200 IntegerCacheExample
代码示例:
java">public class IntegerCacheExample {public static void main(String[] args) {Integer a = 200; // 使用缓存Integer b = 200; // 使用缓存System.out.println(a == b); // true}
}
输出:
true
4. 其他包装类的缓存机制
代码示例:
java">public class LongCacheExample {public static void main(String[] args) {Long a = 127L; // 使用缓存Long b = 127L; // 使用缓存System.out.println(a == b); // trueLong c = 128L; // 超出缓存范围,创建新对象Long d = 128L; // 超出缓存范围,创建新对象System.out.println(c == d); // false}
}
输出:
true
false
代码示例:
java">public class CharacterCacheExample {public static void main(String[] args) {Character a = 127; // 使用缓存Character b = 127; // 使用缓存System.out.println(a == b); // trueCharacter c = 128; // 超出缓存范围,创建新对象Character d = 128; // 超出缓存范围,创建新对象System.out.println(c == d); // false}
}
输出:
true
false
5. 缓存机制的意义
- 性能优化:
- 缓存机制避免了频繁创建和销毁对象,提高了性能。
- 节省内存:
- 对于常用的小范围值,直接使用缓存对象可以减少内存占用。
- 注意事项:
- 在比较包装类对象时,应使用
equals()
方法而不是==
,因为==
比较的是对象的引用,而不是值。
- 在比较包装类对象时,应使用
代码示例:
java">public class WrapperComparison {public static void main(String[] args) {Integer a = 128;Integer b = 128;System.out.println(a == b); // falseSystem.out.println(a.equals(b)); // true}
}
输出:
false
true
6. 自定义包装类的缓存
代码示例:
java">public class MyInteger {private int value;private static final MyInteger[] cache = new MyInteger[256];static {for (int i = 0; i < cache.length; i++) {cache[i] = new MyInteger(i - 128);}}private MyInteger(int value) {this.value = value;}public static MyInteger valueOf(int value) {if (value >= -128 && value <= 127) {return cache[value + 128];}return new MyInteger(value);}@Overridepublic boolean equals(Object obj) {if (obj instanceof MyInteger) {return this.value == ((MyInteger) obj).value;}return false;}@Overridepublic String toString() {return Integer.toString(value);}
}public class MyIntegerCacheExample {public static void main(String[] args) {MyInteger a = MyInteger.valueOf(127); // 使用缓存MyInteger b = MyInteger.valueOf(127); // 使用缓存System.out.println(a == b); // trueMyInteger c = MyInteger.valueOf(128); // 超出缓存范围,创建新对象MyInteger d = MyInteger.valueOf(128); // 超出缓存范围,创建新对象System.out.println(c == d); // false}
}
输出:
true
false