Java函数的传参机制

最近的一个项目,里面各种返回void,参数用引用类型,那叫一个熟和多,但是也把我绕糊涂了。

我就打算好好理一理java的传参机制,整理一番

很多人一听Java的传参,那一定会脱口而出,java都是值传递的。恭喜各位,答对了。

那么,传的是什么值?

如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的值不会改变原始的值.

如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。

这里我给个代码就很好理解了

 1 public class ParamterTest {
 2     public static void main(String[] args) {
 3         List<Integer> list1 = new ArrayList<>();
 4         List<Integer> list2 = new ArrayList<>();
 5         list1.add(0);
 6         list2.add(0);                          //(1)
 7         f(list1, list2);
 8         System.out.println("list1 2");
 9         p(list1);
10         System.out.println("list2 2");
11         p(list2);                              //(4)
12     }
13
14     public static void f(List<Integer> list1, List<Integer> list2) {
15         list1.add(1);
16         list2.add(1);
17         list2 = new ArrayList<>();             //(2)
18         list1.add(2);
19         list2.add(2);
20         System.out.println("list1 1");
21         p(list1);
22         System.out.println("list2 1");
23         p(list2);                             //(3)
24     }
25
26     public static void p(List<Integer> list) {
27         for (Integer i : list) {
28             System.out.println(i);
29         }
30     }
31 }

输出结果

list1 1
0
1
2
list2 1
2
list1 2
0
1
2
list2 2
0
1

要具体解释,就是涉及到堆,栈和方法区了。

(1)list1,list2刚刚成立,都放进了 0,因为是对象的实例所以保存在堆里面。

(2)list1,list2将自己堆的地址传到了方法里,因为是引用所以保存在栈里面,并通过地址往堆里面的实例,放进了 1。但是,此时new了一个实例,list2在栈里面不再指向堆的实例,而是一个新的地址。

(3)list1,list2放进了2,但此处list1依然指向堆的实例,故放进了 2,而list2则是新的地址,堆的list2并没有放进 2。

(4)方法结束,返回的结果使堆的list1,放进了 1 , 2 。list2 因为在方法内中途有新的实例, 只放进了 1 ,而没有 2。

其实一直迷惑我们,是我们判断出错的是String ,明明是一个引用类型,却是基本类型的特性,因为String 实际上是[]char,具体不细说,我就丢个代码,让大家跑跑吧。

public class ParamterStringTest {
    public static void main(String[] args) {
        String s1 = "a";
        String s2 = "a";
        f(s1, s2);
        System.out.println("s1 2");
        p(s1);
        System.out.println("s2 2");
        p(s2);
    }

    public static void f(String s1, String s2) {
        s1 = "b";
        s2 = "b";
        System.out.println("s1 1");
        p(s1);
        System.out.println("s2 1");
        p(s2);
    }

    public static void p(String s) {
        System.out.println(s);
    }

}

同理,相应的Interge等包装类。

原文地址:https://www.cnblogs.com/ydymz/p/9214216.html

时间: 2024-10-12 08:37:11

Java函数的传参机制的相关文章

浅谈 c++/java/javascript 之传参

本文主要梳理了几种语言的传参机制,即关于 传值.传引用 之争 最近开始学node.js搭后端服务器时,碰到这样一句话 java只有一种传参机制就是传值 javascript其大部分语法规范取自于JAVA语法规范, 那么这种句话也适用于它,于是也有  javascript只有一种传参机制就是传值 为了理解这句话,我从个人感觉较为接近底层的语言c++写一些测试,代码如下 #include<iostream> using namespace std; class Test { public: int

uboot向kernel的传参机制——bootm与tags

最近阅读代码学习了uboot boot kernel的过程以及uboot如何传参给kernel,记录下来,与大家共享: U-boot版本:2014.4 Kernel版本:3.4.55 一 uboot 如何启动 kernel 1 do_bootm uboot下使用bootm命令启动内核镜像文件uImage,uImage是在zImage头添加了64字节的镜像信息供uboot解析使用,具体这64字节头的内容,我们在分析bootm命令的时候就会一一说到,那直接来看bootm命令. 在common/cmd

java复用和传参

java复用和传参的三种方法总结: (1) 直接在一个类中调用函数 : 1 package test1; 2 3 public class a 4 { 5 public static void getDate() 6 { 7 System.out.println("晨落梦公子"); 8 } 9 public static void main(String[] agrs) 10 { 11 getDate(); 12 } 13 } 这种方法应注意主函数中的调用的的getDate()必须声明

PHP_零基础学php_3PHP函数、传参函数、默认参数、函数返回值

<?php function say_hello() //无参数 { $name="tang"; echo "hello,".$name; echo "<br />"; echo "<hr />"; } say_hello();//函数调用 function say_helloS($some_name)//有参数 { echo "hello,".$some_name; echo

C#为什么不能像C/C++一样的支持函数只读传参

C#为什么不能像C/C++一样的支持函数只读传参? 这个问题其实问的人挺多的,我自己也经常想实现这个功能,但是发现总是那么的不尽人意. 有些人倒是给出了一下答案,但是都不能很好的解决像C/C++一样的支持函数只读传参这个问题. 其实这块我觉得我们可能有个误区.就是我们为什么要这样做呢?这样做的目的是什么?对了就是这个.答案也在这里面.关键就在这目的上.我们用C/C++可能有 function(Data const * const pcData),但是在C#里面没有了.感觉似乎少了点什么.对就是少

函数间传参实例(前一个函数产生的数据传到给后一个函数应用)

场景描述:A函数通过一系列的请求与执行,创建并产生订单 B函数获取该订单,然后查询该订单,获取订单信息 本次实例的关键就是,A产生的订单号,传给B,实现函数间传参 代码如下: import requests # 先导入包,这是必须的 import json ordid="190416111501017074" #A函数产生的订单号,具体过程不在此书写 #ordid为定义的变量,需要写到下面函数的括号中,可理解为把变量ordid传到函数search中 def search(ordid):

Python之函数(一)定义函数以及传参

定义函数以及传参 函数的定义 def 函数名(): 函数体 例子: def func():#def关键字--定义 func函数名--和变量定义规则一样 ()必须要写格式 :声明 语句结束 s=[1,2,3] count=0 for i in s: count+=1 print(count) 调用函数: def my_len(): s = (1,2,23,3,4,5,6) count = 0 for i in s: count += 1 print(count) #调用函数 函数名+() myle

C++类成员函数的传参问题

最近代码中经常会出现,成员函数传参经常会发生值传不进去的情况,也是比较低级的错误,这里整理一下供大家参考一下.   (1)成员变量名与形参名相同 World::World(unsigned maxContacts, unsigned iterators) { resolver = iterators; maxContacts = maxContacts; contacts = new ParticleContact[maxContacts]; calculateIterations = (ite

js函数的传参问题

<!Doctype html> <html> <head> <title>js的传参问题</title> <script type="text/javascript"> function get(username) { alert(username); } </script> </head> <body> <input type="button" val