技术清单
申明:本文属于整理加工原创,部分举证材料来自于网络,仅用于学习参考。
本文主要介绍java数据结构相关知识,通过本文讲解,你可以明白:
1、Java支持的基本数据类型有哪些,他们占用的字节大小分别是多少?
2、char 型变量中能不能存贮一个中文汉字?为什么?
3、什么是装箱和拆箱?实现的原理是什么?
4、int 和Integer 有什么区别?字符串的反转及替换?
5、String与StringBuffer区别?
6、枚举(Enumeration)与向量(Vector)的概念和实现原理的理解?
技术解析
一、Java支持的基本数据类型有哪些,他们占用的字节大小分别是多少?
数据类型 | 字节 | 默认值 |
byte | 1 | 0 |
short | 2 | 0 |
int | 4 | 0 |
long | 8 | 0 |
float | 4 | 0.0f |
double | 8 | 0.0d |
char | 2 | '\u0000' |
boolean | 根据编译系统确定,按定义用1个字节表示 | false |
二、char 型变量中能不能存贮一个中文汉字?为什么?
在Java中,char类型占2个字节,而且Java默认采用Unicode编码,以个Unicode码是16位,所以一个Unicode码占两个字节,Java中无论汉子还是英文字母都是用Unicode编码来表示的。所以,在Java中,char类型变量可以存储一个中文汉字(特殊字符除外)。
注意: 在C语言中,char类型占1一个字节,而汉子占2个字节,所以不能存储。
三、什么是装箱和拆箱?实现的原理是什么?
简单一点说,装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。
因此可以用一句话总结装箱和拆箱的实现原理和实现过程:
装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的 xxxValue方法实现的。(xxx代表对应的基本数据类型)
下面是java8种基本类型的自动装箱代码实现。如下:
//boolean原生类型自动装箱成Boolean
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
//byte原生类型自动装箱成Byte
public static Byte valueOf(byte b) {
final int offset = 128;
return ByteCache.cache[(int)b + offset];
}
//byte原生类型自动装箱成Byte
public static Short valueOf(short s) {
final int offset = 128;
int sAsInt = s;
if (sAsInt >= -128 && sAsInt <= 127) { // must cache
return ShortCache.cache[sAsInt + offset];
}
return new Short(s);
}
//char原生类型自动装箱成Character
public static Character valueOf(char c) {
if (c <= 127) { // must cache
return CharacterCache.cache[(int)c];
}
return new Character(c);
}
//int原生类型自动装箱成Integer
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
//int原生类型自动装箱成Long
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
//double原生类型自动装箱成Double
public static Double valueOf(double d) {
return new Double(d);
}
//float原生类型自动装箱成Float
public static Float valueOf(float f) {
return new Float(f);
}
通过分析源码发现,只有double和float的自动装箱代码没有使用缓存,每次都是new 新的对象,其它的6种基本类型都使用了缓存策略。
使用缓存策略是因为,缓存的这些对象都是经常使用到的(如字符、-128至127之间的数字),防止每次自动装箱都创建一此对象的实例。
而double、float是浮点型的,没有特别的热的(经常使用到的)数据的,缓存效果没有其它几种类型使用效率高。
现在我们举几个例子,看看大家明白没。以下代码,大家看看输入结果是什么?
public class Main {
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 322;
Integer f = 322;
Long g = 3L;
Long h = 2L;
int i = 3;
long j = 3;
int k = 322;
System.out.println("1_" + (c == d));
System.out.println("2_" + (e == f));
System.out.println("3_" + (c == new Integer(d)));
System.out.println("4_" + (e.equals(f)));
System.out.println("5_" + (c == (a + b)));
System.out.println("6_" + (c.equals(a + b)));
System.out.println("7_" + (g == (a + b)));
System.out.println("8_" + (g.equals(c)));
System.out.println("9_" + (g.equ