找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2798|回复: 1

Java传递引用类型的实质和多方法实例教程

[复制链接]

65

主题

111

回帖

1557

积分

软件定制初级客户

积分
1557
发表于 2016-9-27 14:24:13 | 显示全部楼层 |阅读模式
首先看java代码如下:

import java.util.Scanner;

import org.junit.Test;

public class TestCoreJava {

@Test

public void testString() {

String original = "原来的值";

modifyA(original);

System.out.println(original);

StringBuffer sb = new StringBuffer();

sb.append(original);

modifyObject(sb);

System.out.println(sb.toString());

}

public void modifyA(String b) {

b = "改变的值";

}

public void modifyObject(StringBuffer object ) {

String b = "改变的值";

StringBuffer sb1 = new StringBuffer();

sb1.append(b);

//object.append(b); 在object指向的引用没改变之前,调用append方法对其指向的堆内存中内容进行修改,是可以达到修改原始StringBuffer对象sb的存放内容这个目的的。

object = sb1;

}

}

  说明:除开八种基本类型之外,在java中其余类型都是引用类型,包括String也是引用类型,传递的也是引用。

我原以为,既然传递的是引用,那么String对象original交由方法modifyA处理后,original存放的值应该变为“改变的值”

同样StringBuffer对象sb存放的值也应该改变成“改变的值”,但是结果却没有,输出都为“原来的值”,然后我就怀疑是否他们传递的不是引用

原来:modifyA(String b)方法在被调用时,original传递给该方法,该法是创建了一个新的String对象b,它也将引用指向original对象指向的那块

堆内存。而我在modifyA方法中使用语句:b = "改变的值";该语句并不能够到达改变original对象的目的,他紧紧将b对象的引用地址改为指向“改变的值”

这个对象所在的堆内存。所以original对象还是指向原来的堆内存,当然他的输出结果不变,同样的问题对StringBuffer对象sb也存在。

  所以可以看出,没有到达期望结果的原因是使用“=”赋值运算符,他修改了副本对象(被调用方法自己创建的中间对象,比如modifyA方法创建的b)的引用地址,

使他指向了不同的堆内存(这对原始的对象内容是没有影响的),而没有实际修改他指向的堆内存中具体值导致的意外。

所以 modifyObject方法中那条被注释语句可以达到修改原始内容的目的.


QQ截图20160923101820.jpg

65

主题

111

回帖

1557

积分

软件定制初级客户

积分
1557
 楼主| 发表于 2016-9-27 14:26:23 | 显示全部楼层
实例教程2

加深对基本类型和引用类型的理解;
【效果图】
[附件已丢失]

【分析】
  • 参见最后的【参考资料】【解决方案】

【代码】 public void test() throws Exception {
        System.out.println("\nint:=================");
        int i = 2;
        System.out.println("before:" + i);
        change1(i);
        System.out.println("after:" + i);

        System.out.println("\nInteger:=================");
        Integer integer = 3;
        System.out.println("before:" + integer);
        change2(integer);
        System.out.println("after:" + integer);

        System.out.println("\nString:=================");
        String str = new String("xxx");
        System.out.println("before:" + str);
        change3(str);
        System.out.println("after:" + str);


        System.out.println("\nString[]:=================");
        String[] array = new String[]{"a", "b", "c"};
        System.out.println("before:" + array[0]);
        change4(array);
        System.out.println("after:" + array[0]);

        System.out.println("\nBook:=================");
        Book book = new Book("book1");
        System.out.println("before:" + book.name);
        change5(book);
        System.out.println("after:" + book.name);

        System.out.println("\nint[]:=================");
        int[] int_array = new int[]{1, 2, 3};
        System.out.println("before:" + int_array[0]);
        change6(int_array);
        System.out.println("after:" + int_array[0]);
    }


    public void change1(int i) {
        i = 4;
    }

    public void change2(Integer integer) {
        integer = (Integer) 8;
    }

    public void change3(String str) {
        str = new String("yyy");
    }

    private void change4(String[] array) {
        array[0 = "A";
    }

    private void change5(Book book) {
        book.name = "book2";
    }

    private void change6(int[] int_array) {
        int_array[0 = 10;
    }

    private class Book {
        public String name;

        Book(String name) {
            this.name = name;
        }
    }

【参考资料】
  • java到底是值传递还是引用传递? (其中“三:调用方法时发生了什么?”讲的很清晰)
    file:///C:/Users/Lou/Documents/My%20Knowledge/temp/ef8ebd47-5d9c-439f-a076-099ab2f4f6de_4_files/a1cd73ce-0ff3-45de-a06d-9fa0918bf9dc.png
    [附件已丢失]

  • Java之基本类型和引用类型、引用传递和值传递、“==”和equals()
  • java 中 Integer 传参方式的问题,不是说Integer是引用传递么?但为什么不会改变it
    file:///C:/Users/Lou/Documents/My%20Knowledge/temp/ef8ebd47-5d9c-439f-a076-099ab2f4f6de_4_files/2268a9db-dbe3-4270-a3a5-a531b3d8a2f4.png
    [附件已丢失]

    [附件已丢失]

    file:///C:/Users/Lou/Documents/My%20Knowledge/temp/ef8ebd47-5d9c-439f-a076-099ab2f4f6de_4_files/a8cfde6d-9934-497a-8798-3725128d53c3.png
  • String 和 Integer 传递给方法时到底是不是传递引用??!!
    When the argument is of reference type, pass-by-value means that the method cannot change the object reference, but can invoke the object's methods and modify the accessible variables within the object.
    当参数是引用类型时,你能通过调用该引用所指向的对象本身的方法来改变对象自身,但是,你并不能改变该引用。(你改变的只能是引用所指向的对象,而不是引用。所以,仍然是值传递。)
  • JAVA 值传递还是引用传递
    不管你传的是什么,传过去的都只是一个副本而已,这个副本作为方法的局部变量保存在栈中。
    如果传的是基本数据类型,修改这个值并不会影响作为参数传进来的那个变量,因为你修改的是方法的局部变量,是一个副本。
    如果传的是一个对象的引用,也是一样的,也是一个副本,但是这个副本和作为参数传进来的那个引用指向的是内存中的同一个对象,所以你通过这个副本也可以操作那个对象。但是如果你修改这个引用本身,比如让他指向内存中的另外一个对象,原来作为参数传进来的那个引用不会受到影响。
    我觉得弄明白这些就行了,说值传递或引用传递都无所谓,但是说值传递更适合一些,这个值可以是引用也可以是基本数据类型。


20160326080046094.jpg
20160326080057661.jpg
20160326080121083.jpg
20160326080133001.jpg
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|

GMT+8, 2026-10-22 11:26

安卓脚本软件 · 键鼠盒子 · HID · 机械臂

快速回复 返回顶部 返回列表

随机推荐 · 热帖 / 新帖 / 随便看看

社区会员(随机展示)