引言
在面试的时候,一般会有部分java基础部分的面试题。而一般会有问输出结果的题目,其考察的是面试者对java中值传递和引用传递的理解。那么,今天我们就来聊一聊java中的值传递与引用传递。首先,在java中数据类型分两大类:基础数据类型和引用数据类型,请看下图:
首先,我们通俗的表述下什么是值传递和引用传递。
值传递:在传递的过程中是将值直接传递过去,接收者拿到的是实际的值,相当于拷贝了一份一模一样的数据,接收者对该值的改变并不影响原定于的值。
引用传递:传递的是数据在内存中所指向的引用,接收者对数据的改变会影响原值。
经过查阅相关资料得知,在java中基本数据类型的传递是按值传递,引用数据类型是按引用传递。但有个特例,String类型是按值传递的。
我们先验证byte的传递方式:
//基本类型byte
byte byte1 = (byte) 0xA;
byte byte2 = (byte)0xB;
swapByte(byte1,byte2);
Log.e(TAG,"byte1="+byte1+" byte2="+byte2);
private void swapByte(byte byte1,byte byte2){
byte temp = byte1;
byte1 = byte2;
byte2 = temp;
Log.e(TAG,"swapByte byte1="+byte1+" byte2="+byte2);
}
我们定义2个byte类型的变量byte1、byte2,然后用swapByte交换byte1、byte2并在打印交换后的数据及原数据。结果如下:
swapByte byte1=11 byte2=10
byte1=10 byte2=11
可以看到在交换之后并不影响原数据,与预期相符,按值传递。
我们在看下我们日常用得较多的int类型
//基本类型int
int int1 = 1;
int int2 = 9;
swapInt(int1,int2);
Log.e(TAG,"int1="+int1+" int2="+int2);
private void swapInt(int int1,int int2){
int temp = int1;
int1 = int2;
int2 = temp;
Log.e(TAG,"swapInt int1="+int1+" int2="+int2);
}
与byte类似,也是交换两个int型数据并打印结果如下:
swapInt int1=9 int2=1
int1=1 int2=9
可以看到也是值传递,与预期也是相符的。
下面我们看下List是否按我们的预期引用传递的,代码如下:
//集合类型 采用的是引用传递
List<String> stringList = new ArrayList<>();
for (int i = 0; i < 5; i++){
stringList.add("String"+i);
}
changStringList(stringList);
for (String str : stringList){
Log.e(TAG,str);
}
private void changStringList(List<String> stringList){
stringList.remove(0);
for (String str : stringList){
Log.e(TAG,"changStringList "+str);
}
}
我们先构建了一个列表,然后赋值,在changeStringList中移除到第0个字符串,并打印改变后的数据及原数据,结果如下:
changStringList String1
changStringList String2
changStringList String3
changStringList String4
String1
String2
String3
String4
可以看到改变之后原数据的数据也跟着改变了,因为集合是按引用传递的,他们所改变的是同一份数据。
我们在上面试了基本数据类型和集合数据类型,那么我们看下在开始的时候所提到的特殊的那个String类型。String在java中实际是一个类类型。
//String
String string1 = "string1";
String string2 = "string2";
swapString(string1,string2);
Log.e(TAG,"string1="+string1+" string2="+string2);
private void swapString(String string1,String string2){
String temp = string1;
string1 = string2;
string2 = temp;
Log.e(TAG,"swapString string1="+string1+" string2="+string2);
}
代码运行结果如下:
swapString string1=string2 string2=string1
string1=string1 string2=string2
可以发现String交换后并不影响原值。
其余的类型就留待小伙伴们自行验证吧。这里给出结果:基本数据类型按值传递,引用数据类型按引用传递,类类型的String是一个特例,按值传递。
思考,以下代码的运行结果(一般面试题也会带)
//demo1
String str=new String("hello");
char []chs={'w','o','r','l','d'};
change(str, chs);
System.out.println(str+" "+new String(chs));
//-------------------------------------------------
//demo2
StringBuffer sb=new StringBuffer("hello");
change(sb);
System.out.println(sb);
public void change(StringBuffer sb)
{
sb.append(" world");
}
public void change(String str,char[]chs)
{
str.replace('h', 'H');
chs[0]='W';
}
感兴趣的小伙伴可以运行下看与自己心中的答案是否一致。
国际惯例,附上测试代码:https://gitee.com/calm1516/JavaPass.git