基本数据类型和引用数据类型
基本数据类型
Java中有八种基本数据类型,都是Java语言预先定义好的,并且是关键字。
这八种基本类型分别是:
- 整型 (4种)
byte
,short
,int
,long
- 字符型 (1种)
char
- 浮点型 (2种)
float
,double
- 布尔型(1种)
boolean
No. | 数据类型 | 大小/位 | 可表示数据范围 | 默认值 |
---|---|---|---|---|
1 | byte (字节型) |
8 | -128~127 | 0 |
2 | short (短整型) |
16 | -32768~32767 | 0 |
3 | int (整型) |
32 | -2147483648~2147483647 | 0 |
4 | long (长整型) |
64 | -9223372036854775808~9223372036854775807 | 0 |
5 | float (单精度) |
32 | -3.4E38~3.4E38 | 0.0 |
6 | double (双精度) |
64 | -1.7E308~1.7E308 | 0.0 |
7 | char (字符) |
16 | 0~255 | ‘\u0000’ |
8 | boolean (布尔) |
- | true或false | false |
引用数据类型
包括有:类、 接口类型、 数组类型、 枚举类型、 注解类型、 字符串型
String
类型就是引用类型
基本、引用 区别
- 基本变量类型
- 在方法中定义的非全局
基本数据类型
变量的具体内容是存储在栈中的
- 在方法中定义的非全局

public static void main(String[] args){
int msg = 100;
// 在将msg给fun方法时,开辟为temp开辟新的内存空间
fun(msg);
}
public static void fun(int temp){
temp = 0;
// 结束调用时释放temp开辟的内存
}

- 引用变量类型
- 只要是
引用数据类型
变量,其具体内容都是存放在堆中的,而栈中存放的是其具体内容所在内存的地址
- 只要是
public static void main(String[] args){
// 1 初态时,初始化book 类型
Book book = new Book("Java开发指南",66.6);
// 2 调用方法:调用时开辟新的temp栈,指向原有引用变量栈堆
fun(book);
}
public static void fun(Book temp){
// 3 设置值
temp.setPrice(99.9);
// 4 结束时释放引用数据类型temp
}
class Book{
String name;
double price;
public Book(String name,double price){
this.name = name;
this.price = price;
}
public void setPrice(double price){
this.price = price;
}
}

三种常见的引用时变量赋值:
String s1 = new String("myString");
String s2 = "myString";
String s3 = "my" + "String";
第一种:new
在程序编译期,编译程序先去字符串常量池检查,是否存在“myString”,如果不存在,则在常量池中开辟一个内存空间存放“myString”;
(new 时,毫无疑问会在堆中分配内存,创建一个String类对象。s1这个在栈中引用指向是队中的String对象)
如果存在的话,则不用重新开辟空间,保证常量池中只有一个“myString”常量,节省内存空间,就只需要创建一个堆中的String对象。
然后在内存堆中开辟一块空间存放new出来的String实例,在栈中开辟一块空间,命名为“s1”,存放的值为堆中String实例的内存地址,这个过程就是将引用s1指向new出来的String实例

String s1 = new String("hello");
String s2 = "hello";
String s3 = new String("hello");
System.out.println(s1 == s2); // false 比较两个引用地址 (s2-> 常量池地址) (s1 -> String对象地址)
System.out.println(s1.equals(s2)); // true equals()比较字符串的内容
System.out.println(s1 == s3); //false 每个String 对象都不是不同的,引用地址也不同
第二种:直接定义
在程序编译期,编译程序先去字符串常量池检查,是否存在“myString”,
如果不存在,则在常量池中开辟一个内存空间存放“myString”;如果存在的话,则不用重新开辟空间。
然后在栈中开辟一块空间,命名为“s1”,存放的值为常量池中“myString”的内存地址

String str1 = "hello";
String str2 = "hello";
System.out.println(str1 == str2); // 返回true
// 因为 == 是判断地址位置。str1没发现hello
// 会先到常量池中检查是否有“hello”的存在,发现是没有的,于是在常量池中创建“hello”对象,并将常量池中的引用赋值给str1
// 第二个字面量 String str2 = "hello",在常量池中检测到该对象了,直接将引用赋值给str2
第三种:使用+号连接
String s1 = "a" + "b";
String s2 = "ab";
System.out,println(s1 == s2);//true ,s1 和 s2 地址是一样的
具体的原理我目前并没有理解透彻,推荐去看《thinking in Java》
String的intern()方法
转载至《thinking in java》
https://blog.csdn.net/sureyonder/article/details/5569366
如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符添加到常量池中,并返回此String对象的引用
String类的intern()方法可以截留字符串,如果String对象包含的字符序列不在字符串常量内部列表中,那么就把这个String对象包含的字符序列和String对象的引用作为名值对保存到内部列表中,最后intern()返回一个指向String对象本身的引用;如果 String对象包含的字符序列在字符串常量内部列表中,那么就返回列表的名值对中的对应的字符串对象引用,而String对象本身的就会被丢弃
intern()方法在不同的jdk中有不同的作用分为1.6前和1.7后
String(简单版。233)
- String类型其实并不是基本类型,一旦创建就不能够被改变
- String类使用了final修饰符,不能被继承
// String类的成员变量定义,不可变
private final char value[];
private final int count;
整型
字符型
- char类型用于存放一个字符,值用单引号’表示 (双引号表示字符串)
- 其长度和short一样,也是16位的
浮点型
- float 长度为32位
- double 长度为64位
- 默认情况下:定义小浮点型都是使用double类型
double d = 123.45;
// 出现编译错误,因为54.321超过32位,需要转换为double
float f = 54.321;
// 往数值后面加f,声明为float
float f2 = 54.321f;
字面值
给基本类型的变量赋值的方式叫做 字面值
// 例如
int a = 1
float fl = 23.1
// 整形字面型
long val = 26L; //以L结尾的字面值表示long型
int decVal = 26; //默认就是int型
int hexVal = 0x1a; //16进制
int oxVal = 032; //8进制
int binVal = 0b11010; //2进制
// 浮点数字面值顶折
float f1 = 123.4F;// 以F结尾的字面值表示float类型
double d1 = 123.4;// 默认就是double类型
double d2 = 1.234e2;// 科学计数法表示double
// 字符型和转义
String str = "这是字符串"
char newLine = '\n'; //换行
char doubleQuote = '\"'; //双引号
易错点:
byte b = 200 会报错
解:byte一共八个bit位,最高位表示正负,所以范围是-128~127
类型转换
不同类型之间的数据可以互相转换,