`
zhanghonglun
  • 浏览: 92462 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

解释传值,传引用?String参数的困惑

 
阅读更多
		
public static void main(String[] args) throws Exception {
		String str="aaaaaaaa";
		change(str);
		System.out.println(str);
	}

	public static void change(String str){
		str="bbbbbbb";
	}

结果是aaaaa,而不是改变过的bbbbb.

解释:

对象是传引用(准确说应该是指针,Java 中没有C 意义上的引用),但是如果引用的是个String对象,情况就不同,因为String 一旦创建就不能改变,这才是关键(本质)。

在change 方法中给该方法的局部变量str 重新赋值时,因为str 指向的位置是String 常量池,是不能改变的,所以只能产生一个新的String 对象,change 方法中的str 指向新的对象,而main 方法中的str 变量还是指向之前产生的对象。

这跟一般的传引用是不一样的,因为一般的引用可以改变其指向的地址上的对象值,所以传来传去如果大家还是指向同一个地址,一改全部都改变了。LZ 可以用StringBuffer 试试,结果和你预期的就会一致。如下面的代码

	public static void main(String[] args) throws Exception {
		StringBuffer str=new StringBuffer("aaaaaaaa");
		change(str);
		System.out.println(str);
	}

	public static void change(StringBuffer str){
		str=str.replace(0, str.length(), "bbbbbbbb");
	}

 
也就是说,如果修改了引用指向的地址的内容,所有指向该地址的引用都会受到影响,这才是传引用的根本所在。

 

使用String s="" 的方式产生的String 对象会被放入String 常量池中,而String 常量池中相同的String 对象只会有一个Copy ,故,

	public static void main(String[] args) throws Exception {
		String str1="aaaaaaaa";
		String str2="aaaaaaaa";
		System.out.println(str1==str2);
	}

将输入true. 而使用new String 产生的对象就跟一般的对象一样,会在普通的Heap 中,此对象会同时被加入String常量池(不是很好验证),

	public static void main(String[] args) throws Exception {
		String str1=new String("aaaaaaaa");
		String str2=new String("aaaaaaaa");
		System.out.println(str1==str2);
	}

将输出false.

分享到:
评论
4 楼 mikey_java 2012-06-16  
3 楼 lovejavaei 2009-07-03  
关与这个问题,其实,统一按传值来理解最简单,只不过,不同的情况,值是不一样的。
2 楼 zhanghonglun 2009-06-22  
同意你的看法。
传引用的本质就是要去改变引用指向的地址对应的内容。如果是
Object o1 = new Object();
Object o2=o1;

这时o1,o2 指向Heap 里同一个地址,直接操该地址里的信息,o1,o2 都会受影响。但如果写
Object o1 = new Object();
Object o2=o1;
o2=new Object();
这是在Heap 中产生了一个新的对象,o2 指向它,o1 不受影响。

可能有些人会误解,
Stirng s1 = "aaaaa";
String s2=s1;
s2="bbbbb";
就是直接对s1,s2 指向的地址做了修改,而不知道s1,s2 指向的是data segment 中的常量池,是不可以修改的,所以只能为s2 产生一个新的对象。
1 楼 fuliang 2009-06-22  
你说的那个不是本质,本质是传递引用,但是是值传递,引用生成了副本。
你举的例子也不是恰当的
对应的例子
public static void change(StringBuffer str){ 
    str=new StringBuffer("bbbbbbb");

效果也是输出aaaaa
你那个只是在说明String是个不变类型,改变就生成副本。
其实楼主并没有改变对象,只是引用副本指向改变而已。

相关推荐

    java中传值还是传引用的的认识

    "java中传值还是传引用的认识" Java 中的参数传递是值传递还是引用传递?这是一个经常引发讨论的问题。在 Java 中,参数传递是按值传递的,也就是说,传递给方法的参数是一个副本,而不是原始值本身。 当一个对象...

    Java是传值还是传址引用

    ### Java是传值还是传址引用 #### 一、简单类型是按值传递的 Java在处理简单数据类型(如int、boolean等)时采用的是按值传递的方式。这意味着当你将一个简单类型的值作为参数传递给一个方法时,实际上传递的是这...

    JAVA中传值与引用问题

    在计算机编程领域,特别是对于面向对象语言如Java而言,“传值”与“传引用”的概念是理解数据传递机制的关键所在。Java作为一种广泛使用的高级编程语言,在设计之初就考虑到了如何避免C/C++等语言中的复杂性,特别...

    Java中的传值与传引用实现过程解析

    Java中的传值与传引用是Java编程语言中的一种基础概念,它们是Java函数中参数传递的两种方式。 Java中的传值是指函数参数的值被复制到函数内部,在函数内部对参数的修改不会影响原来的参数值。 Java中的传引用是指...

    android activityIntent 传值 传对象

    - 为了保持代码的可读性和可维护性,建议为每个传递的参数创建唯一的键(key)。 在项目`YQY_IntentTest`中,可能包含了相关的测试代码,你可以通过查看这些代码来更好地理解Intent在实际应用中的使用。在实际开发...

    String作为形式参数传递给方法的情况

    二、 Java 中的“传值”和“传引用”问题 在 Java 中,基本类型作为参数传入方法时,方法操作的是参数变量的一个拷贝,而非变量本身。这叫做“值传递”。例如,在上面的代码示例中,我们将整数变量 `number` 传递给...

    vue prop属性传值与传引用示例

    vue组件在prop里根据type决定传值还是传引用。 简要如下: 传值:String、Number、Boolean 传引用:Array、Object 若想将数组或对象类型也以值形式传递怎么办呢?如下方式可以实现: // component-A 引用component-...

    JAVA面试题解惑系列传了值还是传了引用?.pdf

    本文将从一个实际的面试题出发,深入探讨Java中的参数传递机制,并解释为什么它被说成是“传值”。 首先,让我们来看一个常见的面试题:“在Java中,是传递对象的引用还是对象的副本?”为了回答这个问题,我们先要...

    浅析Java方法传值和传引用问题

    在Java编程语言中,方法参数传递机制涉及到两个主要概念:传值和传引用。了解这两个概念对于编写高效、可靠的代码至关重要。本篇文章将深入探讨Java中的方法传值和传引用问题。 首先,让我们理解什么是传值。在Java...

    c#几个区别传值和传址的好例子

    在C#编程中,了解和区分传值与传址的概念至关重要,因为这直接影响到函数调用时参数的处理方式,从而影响程序的行为。下面通过两个示例来详细讲解这两个概念。 **传值(Pass by Value)** 在C#中,基本类型(如int...

    后台与页面之间的传值以及页面与页面之间的传值

    在IT行业中,尤其是在Web开发领域,后台与页面之间的传值以及页面与页面之间的传值是至关重要的技术环节。本文将详细讲解这两种通信方式,并以Spring MVC框架为例进行深入阐述。 一、后台(服务器)与页面(客户端...

    acton之间传值

    ### Struts2框架中Action间传值方法详解 在Struts2框架中,Action类是处理用户请求的核心组件,它们负责执行具体的业务逻辑,并决定视图的转向。在某些情况下,我们可能需要在一个Action处理完成后将某些数据传递给...

    Java到底是传引用还是传值Java开发Java经验技巧共

    Java编程语言在处理参数传递时遵循一种特殊的方式,它既不是纯粹的按值传递,也不是纯粹的按引用传递。理解这一点对于深入学习Java至关重要。在Java中,基本数据类型(如int、float、char等)是按值传递的,而对象则...

    普通传值正向传值

    var someData: String? override func viewDidLoad() { super.viewDidLoad() if let data = someData { // 在这里,我们可以在ViewController2中使用接收到的数据 print("接收到的数据:\(data)") } } } `...

    Go语言中的gin框架之GET/POST请求参数接收传值(五)

    Key string `json:"key"` } if err := c.ShouldBindJSON(&data); err != nil { c.JSON(400, gin.H{"error": "Invalid JSON body"}) return } c.JSON(200, gin.H{"message": "Received POST request with JSON...

    C#与JS联合编程的传值

    这里的 `ShopXG` 函数接受一个字符串参数,并弹出一个警告框显示从C#传来的消息。 #### 三、JavaScript调用C#方法 除了C#可以调用JavaScript之外,反方向的通信也是非常常见的需求。下面我们将通过一个具体的例子...

    java及C++中传值传递、引用传递和指针方式的理解.docx

    ### Java及C++中传值传递、引用传递和指针方式的理解 在程序设计语言中,函数调用时参数的传递方式对理解程序的行为至关重要。本文将深入探讨Java与C++这两种广泛使用的编程语言中参数传递的方式,包括值传递、引用...

    C#如何实现窗体传值方法

    将`this`作为参数传递给`ShowDialog()`方法,这样子窗体就能访问到父窗体的对象。 ```csharp FMChild fmChild = new FMChild(); fmChild.ShowDialog(this); fmChild.Dispose(); ``` **方法二**: 设置`Owner`属性...

    深入理解JavaScript中的传值与传引用

    JavaScript中的传值与传引用是理解函数参数传递的关键,它涉及到数据类型的处理方式。在JavaScript中,主要有两种数据类型:基本类型(Primitive Types)和引用类型(Reference Types)。基本类型包括undefined、...

Global site tag (gtag.js) - Google Analytics