基本数据类型
| 类型名称 | 关键字 | 占用内存 | 取值范围 |
|---|---|---|---|
| 字节型 | byte | 1字节 | -128~127 |
| 短整型 | short | 2字节 | -32768~32767 |
| 整型 | int | 4字节 | -2147483648~2147483647 |
| 长整型 | long | 8字节 | -9223372036854775808L~9223372036854775807L |
| 单精确度浮点型 | float | 4字节 | +/-3.4E+38F(6~7 个有效位) |
| 双精确度浮点型 | double | 8字节 | +/-1.8E+308 (15 个有效位) |
| 字符型 | char | 2字节 | |
| 布尔型 | boolean | 1字节 | true 或 false | |
引用数据类型
String类型就是引用类型,还有Double,Byte,Long,Float,Char,Boolean,Short(注意这里和基本类型相比首字母是大写),简单来说,所有的非基本数据类型都是引用数据类型。
基本数据类型和引用数据类型区别
-
存储位置
- 基本变量类型:在方法中定义的非全局基本数据类型变量的具体内容是存储在栈中的
- 引用变量类型:引用数据类型变量,其具体内容都是存放在堆中的,而栈中存放的是其具体内容所在内存的地址
-
传递方式
- 基本数据类型:在方法中定义的非全局基本数据类型变量,调用方法时作为参数是按数值传递的
- 引用数据类型:调用方法时作为参数是按引用传递的
几个相关的问题
-
String 是 java 中的基本数据类型吗?是可变的吗?是线程安全的吗?
String 不是基本数据类型,java 中的基本数据类型是:byte、short、int、long、char、float、double、boolean。
String 是不可变类,一旦创建了 String 对象,我们就无法改变它的值,因此,它是线程安全的,可以安全地用于多线程环境中。
-
为什么要设计成不可变的呢?
String 设计为不可变的原因有如下 3 点:
- 安全:由于 String 广泛用于 java 类中的参数,所以安全是非常重要的考虑点,包括线程安全,打开文件,存储数据密码等等。
- 效率:String 的不变性保证哈希码始终如一,所以在用于 HashMap 等数据结构的时候就不需要重新计算哈希码,提高效率。
- 空间:因为不同的字符串变量可以引用池中的相同字符串,所以可以在java 运行时节省大量的 java 堆空间,如果字符串是可变的话,任何一个变量的值改变,就会反射到其他变量,那字符串池也就没有任何意义了。
-
如果 String 是不可变的,那我们平时赋值的是改了什么呢?
平时使用双引号方式赋值的时候其实是返回的字符串引用,并不是改变了这个字符串对象。
-
String 有哪些创建方式?它们在 JVM 的存储方式是相同吗?
String 常见的创建方式有两种:
第一种:String s1 = “Java”
s1 会先去字符串常量池中找字符串 "Java",如果有相同的字符则直接返回字符串引用,如果没有此字符串则会先在常量池中创建此字符串,然后再返字符串引用。
第二种:String s2 = new String("Java")
s2 是直接在堆上创建一个变量对象,但不存储到字符串池,调用 intern 方法才会把此字符串保存到常量池中。
-
简单讲讲 String,StringBuffer,StringBuilder 的区别?
String 是不可变类,每当我们对 String 进行操作的时候,总是会创建新的字符串。操作 String 很耗资源,所以 Java 提供了两个工具类 StringBuffer 和 StringBuilder 来操作 String。
StringBuffer 和 StringBuilder 是可变类,StringBuffer 是线程安全的,StringBuilder 不是线程安全的。所以在多线程对同一个字符串操作的时候,我们应该选择用 StringBuffer,由于不需要处理多线程的情况,StringBuilder 的效率比 StringBuffer 要高。
-
equals和==的区别
- ==:基本类型比较值,引用类型比较地址。
- equals:对两个对象的地址值进行比较(即比较引用是否相同)
- equals和hashcode之间的关系: 默认情况下,equals相等,hashcode必相等,hashcode相等,equals不是必相等。hashcode基于内存地址计算得出,可能会相等,虽然几率微乎其微。