Java之值传递与引用传递

引言

在面试的时候,一般会有部分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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值