Java基本数据类型
1、基本数据类型大小
数据类型 | 基本类型 | 字节空间 | 范围值 |
---|---|---|---|
整数 | byte | 1字节(8位bit) | -2^7 - 2^7-1 |
整数 | short | 2字节(16位bit) | -2^15 - 2^15-1 |
整数 | int | 4字节(32位bit) | -2^31 - 2^31-1 |
整数 | long | 8字节(64位bit) | -2^63 - 2^63-1 |
浮点数(单精度) | float | 4字节(32位bit) | |
浮点数(双精度) | double | 8字节(64位bit) | |
布尔 | boolean | 存true和false | |
字符串 | char | 单一的16位Unicode字符 |
一个中文所占字节数:UTF-8编码是3个字节、GBK和ISO-8859-1是2个;
一个英文所占字节数:UTF-8、GBK和ISO-8859-1都是1个;
2、数据类型存储
- 基本数据类型的存储原理:基础数据类型储存在
- 引用类型的存储原理:引用类型继承于Object(也是引用类型)都是按照java里面存储对象的内存模型来进行数据存储的,使用java栈内存和java堆内存来进行数据存储,简单来讲:“引用”(存储对象在堆内存上的地址)都存储在有序的栈内存上,而对象本身存储在堆内存上
- 基本数据类型和引用类型的区别主要在于基本数据类型是分配在栈上的,而引用类型是分配在堆上的
3、==和equals()比较
- 比较java基本类型
比较基本类型只能用”==”比较,equals()方法
比较封装类型
“==”比较的内存地址(引用地址)、equals()比较的值;因为封装类重写了equals()方法。Character a = new Character(‘A’);
Character b = new Character('A');
System.out.println(a == b);//fasle
System.out.println(a.equals(b));//true
Integer i1 = new Integer(10);
Integer i2 = new Integer(10);
System.out.println(i1 == i2);//false
System.out.println(i1.equals(i2));//true
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
上面Integer的equal()方法,说明equals()比较的值;接着往下看
补充说明Integer和Long有一个常量池,-128和127之间的值会从缓存中获取。请看下面代码
Integer a = 127;
Integer b = 127;
System.out.println(i1 == i2);//true
System.out.println(i1.equals(i2));//true
Integer a = 128;
Integer b = 128;
System.out.println(i1 == i2);//false
System.out.println(i1.equals(i2));//true
第一个==比较为true,这是因为Integer内部对-128-127之间的值做了缓存,如果在范围之内会从缓存中获取,反编译上面的代码,得到了下面的类
Integer a =Integer.valueOf(127);
Integer b = Integer.valueOf(127);
valueOf源码
static final int low = -128;
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
- 比较String
“==”比较的是内存地址,”equals”比较的是值
String s1 = "latiny";
String s2 = "latiny";
System.out.println(s1 == s2);//true
System.out.println(s1.equals(s2));//true
String s3 = new String("latiny");
String s4 = new String("latiny");
System.out.println(s3 == s4);//false
System.out.println(s3.equals(s4));//true
补充说明Java String和new String()的区别
栈区存引用和基本类型,不能存对象,而堆区存对象。==是比较地址,equals()比较对象内容。
- (1)、String str1 = “abcd”的实现过程:首先栈区创建str引用,然后在String池(独立于栈和堆而存在,存储不可变量)中寻找其指向的内容为”abcd”的对象,如果String池中没有,则创建一个,然后str指向String池中的对象,如果有,则直接将str1指向”abcd””;如果后来又定义了字符串变量 str2=“abcd”,则直接将str2引用指向String池中已经存在的“abcd”,不再重新创建对象;当str1进行了赋值(str1=“abc”),则str1将不再指向”abcd”,而是重新指String池中的”abc”,此时如果定义String str3 = “abc”,进行str1 == str3操作,返回值为true,因为他们的值一样,地址一样,但是如果内容为”abc”的str1进行了字符串的+连接str1 = str1+“d”;此时str1指向的是在堆中新建的内容为”abcd”的对象,即此时进行str1==str2,返回值false,因为地址不一样。
(2)、 String str3 = new String(“abcd”)的实现过程:直接在堆中创建对象。如果后来又有String str4 = new String(“abcd”),str4不会指向之前的对象,而是重新创建一个对象并指向它,所以如果此时进行str3==str4返回值是false,因为两个对象的地址不一样,如果是str3.equals(str4),返回true,因为内容相同。
String s1=”abc”;
String s2=new String("abc");
System.out.println(s1==s2);//false
System.out.println(s1==s2.intern());//true
这是因为intern()方法,String.intern():
检查字符串常量池中是否存在String并返回池里的字符串引用;若池中不存在,则将其加入池中,并返回其引用。
这样做主要是为了避免在堆中不断地创建新的字符串对象。所以第二个是true
比较对象
public boolean equals(Object obj) {
return (this == obj);
}
java中所有对象都是Object类,没有重写equal(),Object中equal()比较的是==
还没有评论,来说两句吧...