转自:http://developer.51cto.com/art/201104/254715.htm

Java到底是传值还是传引用?相信很少有人能完全回答正确。通常的说法是:对于基本数据类型(整型、浮点型、字符型、布尔型等),传值;对于引用类型(对象、数组),传引用。基本类型传值,所有人都不会对此有疑义;问题出在引用类型上。

为引入正题,不妨先看看下面的例子,你能正确给出程序的运行结果嘛?

  1. /**
  2. * @(#)Swap.java
  3. *
  4. *
  5. *  @author
  6. *  @version  1.00 2007/1/5
  7. */
  8. public   class  Swap   {
  9. public  Swap()   {}
  10. public   static   void  main(String[] args)   {
  11. Changer c  =   new  Changer();
  12. String stra  =   " Mighty " ;
  13. String strb  =   " Mouse " ;
  14. c.swap(stra, strb);
  15. System.out.println(stra  +   "   "   +  strb);
  16. String[] strArr  =   new  String[ 2 ] ;
  17. strArr[ 0 ]  =  stra;
  18. strArr[ 1 ]  =  strb;
  19. c.swap(strArr);
  20. System.out.println(strArr[ 0 ]  +    "   "   +  strArr[ 1 ]);
  21. }
  22. static   class  Changer   {
  23. public   < T >   void  swap(T a, T b)   {
  24. T temp  =  a;
  25. a  =  b;
  26. b  =  temp;
  27. }
  28. public   < T >   void  swap(T[] t)   {
  29. if  (t.length  <   2 )   {
  30. System.out.println( " error! " );
  31. return ;
  32. }
  33. T temp  =  t[ 0 ];
  34. t[ 0 ]  =  t[ 1 ];
  35. t[ 1 ]  =  temp;
  36. }
  37. }
  38. }

上面程序的正确运行结果为:

Mighty Mouse

Mouse Mighty

你答对了嘛?

下面我们来分析一下:为什么会出现上面的运行结果?

为分析这个问题,我们必须对程序中的数据在内存中的布局有一定了解。上面main程序中和String相关的变量共有3个,其布局可以用下图所示:

当调用swap(stra, strb)函数时,传递的是引用类型stra、strb的拷贝值,因此函数中任何对参数的改变都不会影响到stra和strb的值;而调用swap(strArr)时,传递的是strArr的拷贝值,程序中对参数的任何改变仍然不会影响到strArr的值,然而swap(T[] t)中改变的并不是strArr的值,而是strArr[0]和strArr[1]的值,也就是引用类型strArr所指向的对象的值,因而strArr[0]和strArr[1]的值发生了变化。

从上面的分析,我们可以得出结论:对于引用类型,其实参数传递时仍然是按值传递的;当然,按引用传递也不是完全没有道理,只是参考对象不是引用类型本身,而是引用类型所指向的对象。

Java经典问题:传值与传引用?的更多相关文章

  1. java 函数形参传值和传引用的区别

    java方法中传值和传引用的问题是个基本问题,但是也有很多人一时弄不清. (一)基本数据类型:传值,方法不会改变实参的值. public class TestFun { public static v ...

  2. java中的传值与传引用

    java函数中的传值和传引用问题一直是个比较“邪门”的问题,其实java函数中的参数都是传递值的,所不同的是对于基本数据类型传递的是参数的一份拷贝,对于类类型传递的是该类参数的引用的拷贝,当在函数体中 ...

  3. Java 函数调用是传值还是传引用? 从字节码角度来看看!

    原文地址:点击打开

  4. Java中的值传递和地址传递(传值、传引用)

    首先,不要纠结于 Pass By Value 和 Pass By Reference 的字面上的意义,否则很容易陷入所谓的“一切传引用其实本质上是传值”这种并不能解决问题无意义论战中.更何况,要想知道 ...

  5. java集合中的传值和传引用

    在学习java集合过程中发现了传值和传引用的区别: 我们来看下面两句话 ●java集合就像一种容器,我们可以把多个对象(实际上是对象的引用),丢进该容器.(来自疯狂java讲义) ●当使用Iterat ...

  6. Java内存管理-Stackoverflow问答-Java是传值还是传引用?(十一)

    勿在流沙筑高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 本文导图: 一.由一个提问引发的思考 在Stack Overflow 看到这样一个问题 ...

  7. 【转载】Java是传值还是传引用

    1. 简单类型是按值传递的 Java 方法的参数是简单类型的时候,是按值传递的 (pass by value).这一点我们可以通过一个简单的例子来说明: /* 例 1 */ /** * @(#) Te ...

  8. Java学习笔记:具体解释传值和传引用

    传值和传引用 When you're passing primitives into a method ,you get a distinct copy of the primitive. When ...

  9. java传值与传引用

    一.传值与传引用 1.不管java参数的类型是什么,一律传递参数的副本. 在thinking in java中,明确指出,如果java是传值,那么传递的是值的副本,如果java传递的是引用,那么传递的 ...

随机推荐

  1. Xamarin.Android之定位

    一.前言 打开我们手中的应用,可以发现越来越多的应用使用了定位,从而使我们的生活更加方便,所以本章我们将学习如何在Xamarin中进行定位的开发. 二.准备工作 因为我们的虚拟机是运行在电脑本地的,自 ...

  2. urlparse基本运用

    # -*- coding: cp936 -*- #python 27 #xiaodeng #urlparse基本运用 import urllib,urlparse def urlparse_test( ...

  3. docker容器日志在哪?以及清理命令

    /var/lib/docker/containers 日志大小限制:传送门 查看所有容器日志大小和清理所有容器日志命令: ls -lh $(find /var/lib/docker/container ...

  4. 【php】(转载)分享一个好用的php违禁词 处理类

    1.直接上代码: <?php //定义编码 header( 'Content-Type:text/html;charset=utf-8 '); $words=array('我','你','他') ...

  5. Utils--封装好的下载图片的方法

    /** * 封装下载图片方法 * @param url 下载地址 * @param filename * @return 下载成功为true */ public boolean downfile(St ...

  6. xml中“ < > ”转义为“ &lt; &gt; ”问题处理

    曾经也碰到过类似问题,解决方法是在发送或者解析报文前执行上面的方法将内容转义一下,现在我用dom4j组装如下的报文(报文体中内容传输时加密处理),大致介绍一下上面方法的使用,具体看代码. import ...

  7. nsTimer的简单用法

    //用nstimer的用法 一种用法,要手动加入到NsRunLoop中 NSTimer *time= [NSTimer timerWithTimeInterval: target:self selec ...

  8. ios中键盘处理适合ipad 和iphone

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UI ...

  9. [转]nonlocal和global

    在Python中,当引用一个变量的时候,对这个变量的搜索是按找本地作用域(Local).嵌套作用域(Enclosing function locals).全局作用域(Global).内置作用域(bui ...

  10. Linux init进程学习 转

    http://oss.org.cn/kernel-book/ch13/13.6.1.htm init进程的建立 Linux将要建立的第一个进程是init进程,建立该进程是以调用kernel_threa ...