Java经典问题:传值与传引用?
转自:http://developer.51cto.com/art/201104/254715.htm
Java到底是传值还是传引用?相信很少有人能完全回答正确。通常的说法是:对于基本数据类型(整型、浮点型、字符型、布尔型等),传值;对于引用类型(对象、数组),传引用。基本类型传值,所有人都不会对此有疑义;问题出在引用类型上。
为引入正题,不妨先看看下面的例子,你能正确给出程序的运行结果嘛?
- /**
- * @(#)Swap.java
- *
- *
- * @author
- * @version 1.00 2007/1/5
- */
- public class Swap {
- public Swap() {}
- public static void main(String[] args) {
- Changer c = new Changer();
- String stra = " Mighty " ;
- String strb = " Mouse " ;
- c.swap(stra, strb);
- System.out.println(stra + " " + strb);
- String[] strArr = new String[ 2 ] ;
- strArr[ 0 ] = stra;
- strArr[ 1 ] = strb;
- c.swap(strArr);
- System.out.println(strArr[ 0 ] + " " + strArr[ 1 ]);
- }
- static class Changer {
- public < T > void swap(T a, T b) {
- T temp = a;
- a = b;
- b = temp;
- }
- public < T > void swap(T[] t) {
- if (t.length < 2 ) {
- System.out.println( " error! " );
- return ;
- }
- T temp = t[ 0 ];
- t[ 0 ] = t[ 1 ];
- t[ 1 ] = temp;
- }
- }
- }
上面程序的正确运行结果为:
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经典问题:传值与传引用?的更多相关文章
- java 函数形参传值和传引用的区别
java方法中传值和传引用的问题是个基本问题,但是也有很多人一时弄不清. (一)基本数据类型:传值,方法不会改变实参的值. public class TestFun { public static v ...
- java中的传值与传引用
java函数中的传值和传引用问题一直是个比较“邪门”的问题,其实java函数中的参数都是传递值的,所不同的是对于基本数据类型传递的是参数的一份拷贝,对于类类型传递的是该类参数的引用的拷贝,当在函数体中 ...
- Java 函数调用是传值还是传引用? 从字节码角度来看看!
原文地址:点击打开
- Java中的值传递和地址传递(传值、传引用)
首先,不要纠结于 Pass By Value 和 Pass By Reference 的字面上的意义,否则很容易陷入所谓的“一切传引用其实本质上是传值”这种并不能解决问题无意义论战中.更何况,要想知道 ...
- java集合中的传值和传引用
在学习java集合过程中发现了传值和传引用的区别: 我们来看下面两句话 ●java集合就像一种容器,我们可以把多个对象(实际上是对象的引用),丢进该容器.(来自疯狂java讲义) ●当使用Iterat ...
- Java内存管理-Stackoverflow问答-Java是传值还是传引用?(十一)
勿在流沙筑高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 本文导图: 一.由一个提问引发的思考 在Stack Overflow 看到这样一个问题 ...
- 【转载】Java是传值还是传引用
1. 简单类型是按值传递的 Java 方法的参数是简单类型的时候,是按值传递的 (pass by value).这一点我们可以通过一个简单的例子来说明: /* 例 1 */ /** * @(#) Te ...
- Java学习笔记:具体解释传值和传引用
传值和传引用 When you're passing primitives into a method ,you get a distinct copy of the primitive. When ...
- java传值与传引用
一.传值与传引用 1.不管java参数的类型是什么,一律传递参数的副本. 在thinking in java中,明确指出,如果java是传值,那么传递的是值的副本,如果java传递的是引用,那么传递的 ...
随机推荐
- 〖Android〗Android源代码所有目录生成的Target(编译生成文件反查)
=> build/tools/zipalign: out/host/linux-x86/bin/zipalign (host) => build/tools/atree: out/host ...
- SpringBoot集成redisson分布式锁
官方文档:https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95 20180226更新:增加tryLock方法,建议后面去掉Distr ...
- Lotus Domino开发心得(一)
—- Lotus Domino 是当今办公自动化系统的主流开发平台之一,目前大部分企业和机构都在使用Lotus Domino 开发自己的无纸办公系统.在开发过程中,我积累了一些小技巧,现在公布出来,希 ...
- Windows下 VS2015编译levelDB(nmake)
VS2015编译levelDB Leveldb是一个google实现的非常高效的kv数据库,非常适合嵌入到程序中.如果有简单的key-value数据库需求,而又想使用一个数据库服务的话,levelDB ...
- Linux的telent服务
目前,在Win/Linux下telnet都很少用了,只是因为数据在传输的过程,未加密!不过在Linux下还是多用于端口探测,今天就来回顾曾经的telnet 1.介绍 Linux被广泛运用到各种服务器及 ...
- Linux下的二进制兼容性的检测
都知道Linux的二进制兼容与windows相比简直是天差地别,windows的二进制兼容做得特别好,很老的游戏都能在windows 10上跑,写的好的程序,在XP上也不是不可以.但是Linux就不一 ...
- los中预览文件
#import <UIKit/UIKit.h> #import <QuickLook/QuickLook.h> @interface ViewController : UIVi ...
- jsp路径问题之base
<base href="<%=basePath%>"> base 标记用于指定页面中所有相对路径的基点, 而默认的相对路径的基点是页面所在路径. 测试代码如 ...
- C语言学习笔记 (006) - 二维数组传参的三种表现形式
# include <stdio.h> # include <stdlib.h> # define M # define N int getdate(int (*sp)[M]) ...
- 【Oracle】详解Oracle中的序列
序列: 是oacle提供的用于产生一系列唯一数字的数据库对象. 自动提供唯一的数值 共享对象 主要用于提供主键值 将序列值装入内存可以提高访问效率 创建序列: 1. 要有创建序列的权限 create ...