数据类型
Java虚拟机中,数据类型可以分为两类:基本类型和引用类型。
- 基本数据类型
- 整型:byte、shot、int、long
- byte
- byte(8位,有符号的,以二进制补码表示的整数
- 最小值是 -128(-2^7),也就是一个字节;最大值是 127(2^7-1);默认值是 0;
- shot
- 数据类型是 16 位、有符号的以二进制补码表示的整数
- 最小值是 -32768(-2^15);最大值是 32767(2^15 - 1);默认值是 0;
- int
- 数据类型是32位、有符号的以二进制补码表示的整数;
- 最小值是-2^31;最大值是2^31 - 1;默认值是 0
- long
- long 数据类型是 64 位、有符号的以二进制补码表示的整数;
- 最小值是-2^63;最大值是2^63 -1;默认值是 0L
- 例子: long a = 100000L,Long b = -200000L
- 为了分辨L最好大写,如果不写L数据会自动变为int类型
- byte
- float、double
- float
- 数据类型是单精度、32位、符合IEEE 754标准的浮点数
- 默认值是 0.0f;
- 浮点数不能用来表示例如货币这样精确地值
- 例子:float f1 = 234.5f。
- double
- 数据类型是双精度、64 位、符合IEEE 754标准的浮点数;
- double类型同样不能表示精确的值,如货币
- 默认值是 0.0d
- 例子:double d1 = 123.4。
- float
- 字符型:char
- char类型是一个单一的 16 位 Unicode 字符;
- 逻辑型:boolean
- 默认值是 false;
- 整型:byte、shot、int、long
- 引用数据类型
包装类
byte->Byte; short->Short; int->Integer; long->Long; double->Double; float->Float; char->Charecter; boolean->Boolean;
Java 编译器对基本类型的自动装箱拆箱:
编译后的class文件:
注意:Integer.valueOf(i),这个函数,当i值在-128~127之间时,不会创建新的对象,但当i值超出这个范围就会新建一个对像,比如:
Integer a = 200;
Integer b = 200;
// 当a和b的值在-128~127之间时,返回true,否则返回false,因此在实际开发中要用 equals 进行比较
// System.out.println(a==b);’
System.out.println(a.equals(b));
为什么会这样?是因为Integer缓存,默认是 -128~127,当然这个值可以配置。
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
当==两边是基本数据类型时,==于比较的是两边的两个值是否相等,当==两边是引用类型时比较的是两个内存地址
另外一些简单但容易出错的代码:
Integer a = 100;
Integer b = 100;
System.out.println(a.equals(b));
System.out.println(a==b);
Integer c = 200;
Integer d = 200;
System.out.println(c.equals(d));
System.out.println(c==d);
int int1 = 100;
int int2 = int1;
int1 = 500;
System.out.println(int1);
System.out.println(int2);
System.out.println(int1 == int2);
int[] arr1 = new int[]{1,2,3,4,5};
int[] arr2 = arr1;
arr1[3] = 8;
System.out.println(arr1[3]);
System.out.println(arr2[3]);
UserVo userVo = new UserVo();
userVo.setUserName("zhangsan");
UserVo userVo1 = userVo;
userVo.setUserName("lisi");
System.out.println(userVo.getUserName());
System.out.println(userVo1.getUserName());
结果为:
true true true false
500
100
false
8
8
lisi
lisi
java equals
结果为 true,false,false
equals是一个普通的方法,该方法返回的结果依赖于自身的实现,所以在进行判断时,要看对应的实现。
- person 对象并没有 equals 方法,但是他会默认继承 Object 类,在 Object 类里有equals 方法如下,实际是判断两个引用是否指向堆内存的同一地址
public boolean equals(Object obj) {
return (this == obj);
}
- Integer 包装类中的 equals 实现如下:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
首先判断传入的对象是否是 Integer 对象,不是直接返回false,是的话再比较值是否相等
- String 中 equals 实现如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
- 如果两个对象指向同一个引用,则返回true;
- 否则判断传入的对象是否是 String 对象
- 判断两个字符串底层 char 数组的长度是否一致
- 循环判断底层数组里的每一个 char 字符,看看是否相等。
String 底层:链接