java变量存储和参数传递机制

java变量存储和参数传递机制


一、Java方法传递机制基本说明

1.形参是基本数据类型

# 传递数据值

2.形参是引用数据类型

# 传递地址值
# 特殊的类型:String、包装类等对象不可变性

举例说明java的不可变性

public class Main {
    public static void main(String[] args) {
        String str="adfada";
        str="yyyy";
        System.out.println(str);
    }
}

输出:yyyy
虽然输出改变了,但是str在改变前后所指向的对象地址是不一样的,java字符串是保存在常量池中,当str=“adfada"时,常量池开辟一个空间存储"adfada”,当str=“yyyy”,常量池又开辟一个空间来存储"yyyy",所以str这个变量所存储的地址变了,因为str前后不同的地址指向常量池中不同的空间。可以看出,存储“adfada”的空间并没有因为str的改变而去存储改变后的字符串“yyyy”。这就是String的不可变性。


二、代码示例说明

请看下面一段代码,先自己试试输出是什么。

package com.lcl.practice;

import org.junit.Test;

import java.util.Arrays;

public class StringTest {
    @Test
    public  void test(){
        int i = 1;
        String str = "hello";
        Integer num = 200;
        int[] arr = {2, 2, 3, 4};
        MyData my = new MyData();
        change(i, str, num, arr, my);
        System.out.println("i = "+i);
        System.out.println("str = "+str);
        System.out.println("num= "+ num);
        System.out.println("arr = "+Arrays.toString(arr));
        System.out.println("my.a = "+my.a);


    }
    public void change(int j, String s, Integer n, int[] a, MyData m){
        j += 1;
        s += "word";
        n += 1;
        a[0] += 1;
        m.a += 1;
    }
}
class MyData{
    int a = 10;
}

输出结果:
i = 1
str = hello
num= 200
arr = [3, 2, 3, 4]
my.a = 11

可以看出,i, str, num都没有改变,arr, my.a改变了。接下来我们就来分析一下。
从代码中我们可以看到,首先定义了变量和对象,其中i基本数据类型,str,num,arr, my 都是引用型数据类型。所以i传递的是值,其它传递的是地址值。如图所示是上述代码各个变量的存储形式。

在这里插入图片描述
可以看到,上述图左边黄色和蓝色区域是方法区(黄色区域为上述代码主方法区即main方法,蓝色区域是change方法区),栈中存的是基本数据类型和堆中对象的引用。右边常量池和堆,堆一般是存放对象和数组,常量池可以存放String字符串。
从左边黄色和蓝色区域可以看到 各个变量或者对象前后的变化。i是基本数据类型,是值传递,所以j存储的值为2。
str是引用数据类型,所以传递的是地址值,所以s的初始值为0x1234,但是由于change()方法使得又在常量池中开辟了两个新的空间存储“word”和“helloword”(String的不可变性),这是s指向“helloword”,所以s存储的地址值需要变,这里假如变成0x9999。
同理,对于n,地址值也变了,从原先的指向堆中的200变成了另外一个空间201(Integer的不可变性)。对于数组a,虽然传递的是地址,也改变了a【0】的值,但是并没有(也不需要)开辟新的空间。所以a存储的地址值没有变。
对于my对象,和数组类似,只是对对象里的值进行了修改,并未创建新的空间。

当chang方法执行完后,形参变量j s n a m都已经消失了。所以现在只需要看黄色区域的变量的值或者指向的对象值就可以了。可以看到,除了数组a[0]变成了2和,my.a变成了11,其它的都没有变化。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值