`
kingxianstar
  • 浏览: 20183 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

Java参数传递中的传值和传址的区别

阅读更多
昨天一个人跑到昆山市区的新华书店,看到了一本叫做《你必须知道的261个java语言问题》,讲的都是一些很基础,但大家几乎都没明白的问题。至少对我来说是这样的。感觉很不错,不过并没有下手,因为新华书店的书都是不打折的,所以准备回来再往上订购。看到其中一个题目就是参数传递中的传值和传址的区别,讲的很清楚。引因为上次面试的时候面试官就问道了我这道题,再会想到自己当时的回答,惭愧啊!
不多说了,早上起来试着自己写了一段代码,以证实书上所讲的内容
public class CallValueOrAddress{
	private String name;
	private int age;

		public void setName(String name){
			this.name=name;
			}
		public String getName(){
			return name;
			}

		public void setAge(int age){
			this.age=age;
			}
		public int getAge(){
			return age;
			}

		public static void main(String agrs[]){
			String str_name="wangxianxing";
			String new_name="nihao";
	    	int int_age=21;
	    	int new_age=22;
        	System.out.println("传值引用");
	    	System.out.println("姓名:"+str_name+"年龄:"+int_age);
	    	new_name=str_name;
	    	new_name=new String("nihaoma?");
	    	new_age=int_age;
	    	new_age=22;
	    	System.out.println("姓名:"+str_name+"年龄:"+int_age);

			CallValueOrAddress cvoa=new CallValueOrAddress();
			cvoa.setName("wangxianxing");
			cvoa.setAge(21);
			System.out.println("传址引用");
			System.out.println("姓名:"+cvoa.getName()+"年龄:"+cvoa.getAge());
			CallValueOrAddress new_cvoa=cvoa;
			new_cvoa.setName("kingxianstar");
			new_cvoa.setAge(22);
			System.out.println("姓名:"+cvoa.getName()+"年龄:"+cvoa.getAge());
			System.out.println("例外情况一");
			new_cvoa=new CallValueOrAddress();
			new_cvoa.setName("kingxianstar+kingxianstar");
			new_cvoa.setAge(32);
			System.out.println("姓名:"+cvoa.getName()+"年龄:"+cvoa.getAge());
			}


	}



运行结果如下:
传值引用
姓名:wangxianxing年龄:21
姓名:wangxianxing年龄:21
传址引用
姓名:wangxianxing年龄:21
姓名:kingxianstar年龄:22
例外情况一
姓名:kingxianstar年龄:22

感觉还不是很全面,所以在网上又搜索了一下,发现了这篇(http://mgc.name/article.asp?id=842)

class Foo {
   private int x;
   public Foo(int x) {
      this.x = x;
    }
    public void setX(int x) {
       this.x = x;
    }
    public int getX() {
       return x;
    }
}

public class Submit {
    static Foo fooBar(Foo foo) {
        foo = new Foo(100);
        return foo;
   }
 
    public static void main(String[] args) {
        Foo foo = new Foo(300);
        System.out.print(foo.getX() + "-");
 
        Foo fooFoo = fooBar(foo);
        System.out.print(foo.getX() + "-");
        System.out.print(fooFoo.getX() + "-");
 
        foo = fooBar(fooFoo);
        System.out.print(foo.getX() + "-");
        System.out.print(fooFoo.getX());
    }
}


What is the output of the program shown in the exhibit?
A. 300-100-100-100-100
B. 300-300-100-100-100
C. 300-300-300-100-100
D. 300-300-300-300-100

Answer: B

涉及知识点:
1.Java中的参数传递有传值和传址两种;
2.基本类型和String型作为参数时,为传值方式,只把值传入方法,不管在方法中怎么处理这个参数,原值不变;
3.其他引用类型作为参数时,为传址方式,将指向内存中的地址传入方法,方法中此内存地址中的值发生变化时,原值也会改变;
4.例外:
    (1)如果引用类型的对象通过传址方式将其指向内存中的地址传入方法后,方法中使用new关键字重新给参数赋值时,会在内存中重新开辟空间,参数指向新的内存空间,此时参数和原对象指向的就不是同一个地址了,参数值的变化不会改变原值;
    (2)String型是引用类型,但是String型作为参数,是传值方式,可以通过以下两种方式来理解:
        <1>String本质上是基本类型的char[],基本类型作为参数时,为传值方式;
        <2> 字符串在内存中是存储在堆中的一个常量,String对象指向内存中这个常量的地址,通过传址方式将地址传入方法后,方法中如果通过字符串给参数赋值,则会重新在堆中创建一个字符串常量,并指向这个地址,原值依然指向原来的字符串常量地址,参数值的变化不会改变原值,如果通过new关键字给参数赋值,参见 (1)中的解释。


解析:
1.“Foo foo = new Foo(300);”,此时foo.getX()的值为300;
2.“Foo fooFoo = fooBar(foo);”,因为Foo是引用类型,main方法中的foo通过传址的方式将其指向的地址传给fooBar方法中的foo,此时两个foo指向同一个地址,foo.getX()的值都为300;通过“new Foo(100)”给fooBar方法中的foo赋值后,该foo重新指向了一个新的地址,foo.getX()的值为新地址中的值100,而main方法中的foo仍然指向原来的地址,foo.getX()的值没有改变,仍为 300;fooBar将foo的值返回给fooFoo,因此fooFoo.getX()的值为100;
3.“foo = fooBar(fooFoo);”,同2中的解释,foo.getX()的值变为100,fooFoo.getX()的值没有变化,仍为100;


另外传值和传址的存储也是不一样的 在传址中有两部分(堆和栈)。
分享到:
评论

相关推荐

    Java是传值还是传址引用

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

    javascript的变量、传值、传址、参数之间关系

    书上说:”把函数外部的值复制给函数内部的参数,就和把值从一个变量复制给另一个变量一样。基本类型的传递如同基本类型变量的复制一样,而引用类型的则如同引用类型变量的复制一样。“  ”当一个变量复制引用类型...

    java面向对象程序设计基础知识总结.pdf

    在Java程序中,方法可以传递参数,包括传值和传址两种方式。传值是将实际参数的值传递给方法,而传址是将实际参数的地址传递给方法。 九、类和对象 在Java程序中,类是对对象的抽象,而对象是对类的具体化或实例化...

    java的类别方法(格式:PPT 字体:繁体)

    Java中的参数传递总是按值传递,意味着方法内部不能直接修改传入参数的原始值,除非参数是对象引用,此时传递的是对象引用的副本,而不是实际对象。 4-6 递归程序设计 递归是解决复杂问题的一种技术,通过将大问题...

    Java实验1-9.pdf

    实验过程中,学生会思考到数组的定义与边界保护问题,以及方法参数传递的不同方式及其对程序行为的影响,例如,了解Java中的“传值”和“传址”概念。 **三、数组与方法应用** 在实验三中,处理成绩数据成为核心...

    java面试题

    - **解析**:Java中对基本类型的传递采用call by value方式,对对象的传递则是传递对象的引用,这类似于call by reference。传递引用本身并不会改变引用的地址,但是可以通过引用改变对象的内容。 7. **类方法...

    7.程序设计语言基础1

    在函数编程中,函数是代码模块化的基础,它们可以通过传值或传址方式进行参数传递。 编译程序是将高级语言程序转换为机器语言或汇编语言的过程。这个过程通常分为六个阶段:词法分析、语法分析、语义分析、中间代码...

    java判断题题库.doc

    Java中的方法调用遵循传值的原则,即使是对象也是传递对象的引用。 51. **非静态方法不能引用静态变量** 错误。非静态方法可以访问静态变量。 52. **静态初始化器是在构造方法被自动调用之前运行的** 正确。...

    java 面试题

    还讨论了参数传递的方式,包括基本类型的传值与引用类型的传址,以及final参数的特殊性。同时,介绍了不同类型之间的转换,包括原始类型转换、String类转换和日期类型转换。 声明和访问控制章节重点讲解了数组的...

    谭浩强C语言教程Word版

    2. **函数**:C语言中的函数是代码模块化的基本单位,教程会讲解如何定义、调用函数,以及函数参数的传递方式(传值与传址)。 3. **指针**:C语言的精髓之一,它允许直接操作内存。教程会深入讲解指针的概念、声明...

    PASCAL精要

    - **函数和过程**:阐述如何定义和调用函数和过程,以及参数传递的方式(传值或传址)。 - **指针和动态内存管理**:解释指针的概念,如何创建和使用指针,以及动态分配和释放内存。 - **文件操作**:教授如何在...

    2021-2022计算机二级等级考试试题及答案No.1494.docx

    - 函数调用时参数传递可以是传值或传址。 - 函数可以返回任何类型的值,包括结构体。 以上知识点涵盖了数据库备份、Java GUI编程、网络通信、网页开发、电子表格操作、内存管理、计算机制作、数据模型、文件处理...

    2021-2022计算机二级等级考试试题及答案No.13685.docx

    这涉及到C/C++等编程语言中的传值与传址概念。 3. Java Applet程序需要导入`java.applet.Applet`包,以便使用Applet类,因此答案B正确。 4. 抽象方法意味着该方法没有具体实现,所在的类必须被声明为抽象类,这是...

    2014年青岛大学《C语言》期末考试试卷.pdf

    C语言支持两种参数传递方式:传值和传址。 - **传值**:函数接收的是参数的副本。 - **传址**:函数接收的是参数的地址。 ### 数组与指针 #### 1. 数组 数组是一种线性数据结构,用于存储同类型的元素集合。可以...

    2021-2022计算机二级等级考试试题及答案No.19095.docx

    - 实参传递给形参时,可以是传值或传址,传址情况下,形参是实参的副本,但它们指向同一内存地址。 13. ASP.NET发布网站: - `App-Code` 文件夹在发布后通常不会存在,因为编译时代码会被合并到输出目录的其他...

    EssentialC

    它们可以接受参数并返回值,分为值参数(传值调用)和引用参数(传址调用)。值参数传递的是参数的副本,不会改变原值;引用参数则传递的是参数的地址,可以修改原值。此外,C语言还支持const关键字,用于声明不可变...

    pascal:用Pascal语言编程

    它们可以有参数,参数传递可以是传值或传址,影响函数或过程内部对参数的修改是否影响调用者。 **4. 结构化编程** Pascal鼓励使用结构化编程方法,如使用子程序、循环和条件语句来构建模块化的程序。这种编程风格...

    2023软考-2023上半年冲刺软件设计师知识点.pdf

    5. **传值调用和传址调用**:函数调用时参数传递的不同方式,前者复制实参值,后者传递实参地址。 6. **翻译阶段**:编译器经过词法分析、语法分析、语义分析后生成目标代码。 7. **符号表**:记录源代码中变量、...

    活动1

    3. **函数**:C语言使用函数组织代码,学习如何定义、调用函数,以及函数参数的传递方式(传值和传址)。 4. **数组和字符串**:数组是一组相同类型的数据集合,字符串是字符数组的特殊形式。了解如何操作数组和...

Global site tag (gtag.js) - Google Analytics