`

java中值传递和引用传递区别

    博客分类:
  • JAVA
阅读更多

 

 

 这段代码的主要部分调用了两个很相近的方法,changeObj()changePri()。唯一不同的是它们一个把对象作为输入参数,另一个把Java中的基本类型int作为输入参数。并且在这两个函数体内部都对输入的参数进行了改动。

  java中的八大基本数据类型:int long float double short byte char boolean

看似一样的方法,程序输出的结果却不太一样。changeObj()方法真正的把输入的参数改变了,而changePri()方法对输入的参数没有任何的改变。

从这个例子知道Java对对象和基本的数据类型的处理是不一样的。和C语言一样,当把Java的基本数据类型(如intchardouble等)作为入口参数传给函数体的时候,传入的参数在函数体内部变成了局部变量,这个局部变量是输入参数的一个拷贝,所有的函数体内部的操作都是针对这个拷贝的操作,函数执行结束后,这个局部变量也就完成了它的使命,它影响不到作为输入参数的变量。

这种方式的参数传递被称为"值传递"。而在Java中用对象的作为入口参数的传递则缺省为"引用传递",也就是说仅仅传递了对象的一个"引用",这个"引用"的概念同C语言中的指针引用是一样的。当函数体内部对输入变量改变时,实质上就是在对这个对象的直接操作。

 

 

class MyDemo {

	public static void operate(StringBuffer x, StringBuffer y) {
		x.append(y);
		y = x;
		System.out.println(x + "," + y);
	}

	public static void main(String[] args) {
		StringBuffer a = new StringBuffer("A");
		StringBuffer b = new StringBuffer("B");
		operate(a, b);
		System.out.println(a + "," + b);
	}
}

结果:
AB,AB
AB,B

 

解释:
很明显你这里传递的是地址(引用)传递2个StringBuffer 对象! 

注意啦: 
x 会指向 a 所指向的内存(可以理解为都指向A),y 会指向 b 所指向的内存,(可以理解为都指向B) 
x.append(y); //这句话把 y 指向的值追加给x指向的值,这个时候x 和a 指向的内存都是AB,y指向的内存仍然是B 
y=x;//这句话就是把 x 的值 附值给 y, 附的是地址! 

这样 a,y,x 同时值向 AB,b仍然指向 B 

System.out.println(x+","+y); 这里所以打印 AB,AB 
System.out.println(a+","+b); 这里所以打印 AB ,B 

引用参数的传递是把原来的地址传递给新的变量,原来引用的仍然在那里! 

 下面还是例子:

//在函数中传递基本数据类型,   
public class Test {   
            
    public static void change(int i, int j) {   
        int temp = i;   
        i = j;   
        j = temp;   
    }   
  
    public static void main(String[] args) {   
        int a = 3;   
        int b = 4;   
        change(a, b);   
  
        System.out.println("a=" + a);   
        System.out.println("b=" + b);   
    }   
}   
  
结果为:   
a=3  
b=4  
原因就是 参数中传递的是 基本类型 a 和 b 的拷贝,在函数中交换的也是那份拷贝的值 而不是数据本身; 

 

public class Test {   
  
    public static void change(int[] counts) {   
        counts[0] = 6;   
        System.out.println(counts[0]);   
    }   
  
    public static void main(String[] args) {   
        int[] count = { 1, 2, 3, 4, 5 };   
        change(count);   
    }   
}   
 结果是:6 
在方法中 传递引用数据类型int数组,实际上传递的是其引用count的拷贝,他们都指向数组对象,在方法中可以改变数组对象的内容。即:对复制的引用所调用的方法更改的是同一个对象。  

 

 

 

这个要和下面的比较下:
class A {   
    int i = 0;   
}   
  
  
public class Test {   
  
    public static void add(A a) {   
        a = new A();   
        a.i++;   
    }   
       
    public static void main(String args[]) {   
        A a = new A();   
        add(a);   
        System.out.println(a.i);   
    }   
}   
  
输出结果是0  
在该程序中,对象的引用指向的是A ,而在change方法中,传递的引用的一份副本则指向了一个新的OBJECT,并对其进行操作。   
而原来的A对象并没有发生任何变化。 引用指向的是还是原来的A对象。

class A {   
    int i = 0;   
}   
  
  
public class Test {   
  
    public static void add(A a) {   
        //a = new A();   
        a.i++;   
    }   
       
    public static void main(String args[]) {   
        A a = new A();   
        add(a);   
        System.out.println(a.i);   
    }   
}   
  
输出结果是1 

 

String 不改变,数组改变
public class Example {   
    String str = new String("good");   
  
    char[] ch = { 'a', 'b', 'c' };   
  
    public static void main(String args[]) {   
        Example ex = new Example();   
        ex.change(ex.str, ex.ch);   
        System.out.print(ex.str + " and ");   
        System.out.println(ex.ch);   
    }   
  
    public void change(String str, char ch[]) {   
        str = "test ok";   
        ch[0] = 'g';   
    }   
}    
程序3输出的是 good and gbc.   
String 比较特别,看过String 代码的都知道, String 是 final的。所以值是不变的。 函数中String对象引用的副本指向了另外一个新String对象,而数组对象引用的副本没有改变,而是改变对象中数据的内容.   
对于对象类型,也就是Object的子类,如果你在方法中修改了它的成员的值,那个修改是生效的,方法调用结束后,它的成员是新的值,但是如果你把它指向一个其它的对象,方法调用结束后,原来对它的引用并没用指向新的对象。

 

分享到:
评论

相关推荐

    Java中值传递和引用传递的区别

    Java中值传递和引用传递的区别详解 Java中值传递和引用传递是两个重要的参数传递机制,它们在程序设计中发挥着至关重要的作用。了解这两种机制的区别对于程序员来说是非常必要的。本文将通过示例代码详细介绍Java...

    JAVA中值类型和引用类型的区别

    总的来说,了解Java中的值类型和引用类型及其区别对于理解和优化代码的性能至关重要。它们在内存管理、参数传递和对象生命周期等方面都有不同的行为,熟练掌握这些概念可以帮助开发者编写出更高效、更稳定的代码。在...

    Python中 传递值 和 传递引用 的区别解析

    首先,我们来解释一下什么是值传递和引用传递。在值传递中,函数接收的是原始数据的一个副本,对这个副本的任何修改都不会影响到原始数据。而在引用传递中,函数接收的则是数据的引用地址,通过这个地址可以对原始...

    java 各公司面试题

    在第一个问题中,涉及到字符串变量`str`的作用域以及Java中值传递与引用传递的概念。Java中,基本数据类型是值传递,而对象(如字符串)则是引用传递。然而,由于字符串在Java中是不可变的,即使在方法中改变了`str`...

    Java当中的内存分配.pdf

    这个例子展示了Java中值传递的特点,即使对象的属性在方法内部被修改,原始对象的属性也会受到影响,这是因为传递的是对象引用的副本,而不是对象本身。这种行为与某些其他语言(如C++或C#)中的引用传递不同,后者...

    定义比较器,比较数组中值大小

    本文将深入探讨如何定义比较器来比较数组中值的大小,并通过一个具体的示例进行说明。 首先,我们需要了解Java中的Comparator接口。Comparator接口提供了一个方法`compare(T o1, T o2)`,用于比较两个对象的顺序。...

    java面试题之try中含return语句时代码的执行顺序详解

    这个规则解释了为何示例代码的输出是0,而不是1,同时也揭示了Java中值传递和对象引用传递的区别。理解这一点对于编写可靠的异常处理代码至关重要,特别是在处理资源清理(如关闭流)等场景时。

    电子类软硬件面试集锦

    答:C++函数的三种传递方式为:值传递、指针传递和引用传递。 2 头文件的作用是什么? 答:一、通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。用户...

    实验二 方法的定义、重载;数组的应用 定义一个数组,并获取该数组中值最小的元素

    实验的源代码`Example24.java`中,`main`方法是程序的入口点,它首先定义了数组`arr`,然后调用`getMin`方法并将数组作为参数传递。`getMin`方法计算出最小值后,`main`方法将其打印出来。运行这段代码,将输出数组`...

    专业试卷中兴\计算机专业试题(01

    6. 将B类对象传递给接受A类引用的func函数,可以通过定义B到A的构造函数或者重载操作符`A()`。 7. `static`关键字在全局变量、局部变量和函数上的区别: - `static`全局变量只在定义它的文件中可见,生命周期始于...

    利用Java8 Optional如何避免空指针异常详解

    在传统的 Java 代码中,我们通常需要在调用可能存在 null 值的方法或字段前进行 null 检查,如上述例子中对 computer、soundcard 和 usb 的多次检查。这种方式虽然可以避免空指针异常,但会使代码变得冗长且不易阅读...

    matlab开发-MUGplusY

    总的来说,MUGplusY是一个基于MATLAB的、具有独特梯度稳定性的中值滤波工具,它通过考虑梯度信息来改进传统中值滤波的性能,适用于各种需要噪声去除和边缘保护的场景。通过深入理解和应用MUGplus.m函数,开发者可以...

    Java统计英文句子中出现次数最多的单词并计算出现次数的方法

    除Java程序设计的相关知识外,文章末尾还推荐了一些对Java学习者有帮助的工具和资料,包括在线字数统计工具、字符统计与编辑工具、Java数据结构与算法教程、Java操作DOM节点技巧总结、Java文件与目录操作技巧汇总...

    java学习笔记

    - **referenced**:引用,指通过引用变量指向对象。 - **variable**:变量,存储数据的标识符。 - **dimension**:维度,通常指数组的维度。 - **defined**:定义,创建类、接口、方法等的过程。 - **conversion**:...

    openCv_JniLibs

    注意,为了优化性能,应尽量减少数据在Java和C++之间的传递,避免不必要的内存拷贝。 总之,OpenCV_JniLibs是一个专门为Android设备上的armeabi-v7a架构编译的OpenCV库,通过JNI接口,可以在Android应用中利用...

Global site tag (gtag.js) - Google Analytics