在java中,分为两大类数据类型:值类型和引用类型。其中,值类型又可以称为基本数据类型
1.值类型(基本数据类型)(byte, short, int, long, float, double, char, boolean)
基本数据类型又可以分为数字类型(整数(byte,short,int,long)和浮点数(float,double))、字符型(char)、布尔型(boolean)
1字节:byte
2字节:short char
4字节:int float
8字节:long double
至于布尔类型(boolean)并没有明确指出占用了多少字节
2.引用类型(除了基本数据类型之外的都是引用类型,枚举是一种特殊的引用类型)
3.方法的值传递
java中,所有的类型都会被分配到内存空间中,基本数据类型只有一块存储空间(被分配在栈中),而引用类型有2块存储空间(一块是存储引用变量的分配在栈中,另一块存储对象的分配在堆中)
以下摘自知乎大神@Intopass的答案
一、基本类型 和 引用类型的不同之处
int num = 10;
String str = "hello";
如图所示,num是基本类型,值就保存在变量中。str是引用类型,变量中保存的只是对象的的地址,一般这种变量称为“引用”。引用指向实际对象,对象中保存着内容。
二、赋值运算符(=)的作用
num = 20;
str = "java";
对应基本类型num,赋值运算符会直接改变变量值,原来的值被覆盖;
对应引用str,赋值运算会改变引用中保存的地址(指向另一个对象),原来的地址被覆盖掉,但是原来的对象不会被改变(还是“hello”)
三、调用方法时发生了什么?参数传递基本上就是赋值操作。
第一个例子:基本类型
void foo(int value) {
value = 100;
}
foo(num); // num 没有被改变
第二个例子:没有提供改变自身方法的引用类型
void foo(String text) {
text = "windows";
}
foo(str); // str 也没有被改变
第三个例子:提供了改变自身方法的引用类型
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder.append("4");
}
foo(sb); // sb 被改变了,变成了"iphone4"。
第四个例子:提供了改变自身方法的引用类型,但是不使用,而是使用赋值运算符。
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder = new StringBuilder("ipad");
}
foo(sb); // sb 没有被改变,还是 "iphone"。
下面是第3个例子图解:
StringBuilder sb = new StringBuilder("iphone");
foo(sb);
void foo(StringBuilder builder) {
builder.append("4");
}
开始在堆内存中创建了一个地址为0x11的StringBuilder对象,对象内容为“iphone”,sb保存着这个对象的地址(0x11),也就是sb指向这个对象;调用方法foo,实际上就是把sb的值0x11赋给了另一个StringBuilder类型的引用builder,此时builder的值也变成了0x11,与sb指向的是同一个对象。所谓值传递,其实就是把变量值赋给方法参数。
builder.append("4")之后,其实就是builder指向的对象的内容发生了改变。
下面是第4个例子的图解:
StringBuilder sb = new StringBuilder("iphone");
foo(sb);
void foo(StringBuilder builder) {
builder = new StringBuilder("ipad");
}
一开始,创建了sb对象,存储的对象地址是(0x11),对象内容为"iphone";调用foo方法,将sb的值(也就是0x11)赋给builder,然后builder也指向"iphone"
builder = new StringBuilder("ipad"); 之后,实际上是在堆内存中创建了一个新的StringBuilder的对象,对象里面保存的值是:"ipad",而builder指向了这个新对象,所以builder的值变成了0x12,不再指向原来地址为0x11的对象了
小结:java中的“=”符号是一种赋值操作,调用方法其实就是将值复制到形参上面。如果参数是基本类型变量,那么就是对值的复制;如果参数是引用类型,那么就是对地址的复制。