再谈Java方法传参那些事
把一个变量带进一个方法,该方法执行结束后,它的值有时会改变,有时不会改变。一开始会觉得--“好神奇呀”。当我们了解java内存分析的知识后,一切都是那么简单明了了--“哦,这么回事呀”。但是今天的上机课,对于引用变量,我犯了一个错误,下面是代码的简化--
void method(int a[]) { int temp[]={1,2,3,4}; a[0]=5; a=temp; }
在这里,我试图把临时数组变量的值赋给a,从而改变实参的值。
方法传参,分传值和传址,基本数据类型变量的传参传的是值;引用变量传参传的是地址。传入的参数,实际是实参的一份拷贝。因为,当我们调用一个方法时,逻辑上,jvm会开辟一个我们称之为栈区的内存,当方法运行结束后,这段内存也就被释放了。我们传入的实参的拷贝的生命也仅限于这段栈区,这便是局部变量的宿命。对于基本数据变量,由于它的值是存在栈区的,且与调用该方法的函数的栈内存是独立的,所以影响不到该函数。引用变量的值是地址,它指向堆区的某个地址,这是一个被共享的内存。我们对其的操作就是操作堆区的数据(继续看下文,这句话是不严谨的)。
这是之前我对传参的理解。用它来理解今天的问题,也是没有问题的。但却忽略了一个问题。
既然传入引用变量是传址的,那么上面的代码为什么不能如愿改变它的值呢?
当我们注意到上文说,传参实际是实参的一份拷贝,引用变量也是如此,而且,引用变量也是存在栈区的。那么,我的“a=temp”是在栈区上改变数据(他们的值仅是地址,不能影响堆内存的对象),而且是拷贝而来的数据。
于是:被调用的方法,在堆内存的操作在方法执行结束后才是有效的。变量名永远是存在栈区的(独立,不被共享),引用变量也是如此。
同样的:
void alg1(int a[])//引用变量指向堆内存对象上的操作,是可以改变传入参数变量的 { int t[]=a;//把a的值,即指向对象的地址赋值给t for(int i=0; i<a.length; i++) t[i]=i; } void alg2(int a[])//虽然看似对该变量的操作,却不是同一个对象的引用了 { int t[]=a;//把a的值,即指向对象的地址赋值给t a=new int[5]; for(int i=0; i<a.length; i++) a[i]=t[i]*t[i]; }
《算法设计与分析》中对于方法调用的描述:
通常,在一份算法中调用另一个算法时,系统需要在运行被调用算法之前完成3件事:
(1)将所有实参指针,返回地址等信息传递给调用算法;
(2)为被调用算法的局部变量分配储存区;
(3)将控制转换到被调用算法的入口。
在从被调用算法返回调用算法时,系统也相应地要完成3件事:
(1)保存被调用算法的计算结果;
(2)释放分配给被调用算法的数据区;
(3)依照被调用算法保存的返回地址将控制转移到调用算法。
再谈Java方法传参那些事的更多相关文章
- java 方法传参方式: 按值调用
程序设计语言中将参数传递给方法的几种方式: 按名调用(call by name): Algol 语言采用此方式, 已成为历史; 按值调用(call by value): 方法接收到的是调用者提供的 变 ...
- Java方法传参,测试在方法内部改变参数内容是否会影响到原值
我分了三种类型的参数进行测试 一.基本类型 public static void main(String[] args) { System.out.println("验证基本类型int作为参 ...
- Java方法传参的问题
1.基本数据类型(byte,short,int,long,float,double,boolean,char)的值传递,不改变其值 2.引用数据类型的值传递,改变其值 3.String类型虽然是引用数 ...
- 浅谈对java中传参问题的理解
之前用的c/c++比较多,在c/c++中对于传参类型,无外乎就是传值.传引用.传指针这几种.但在java中,由于没有指针类型,其传参的方式也发生了相应的变化.在网上找了找,按我之前的理解,java中传 ...
- java的方法传参,最容易混淆的问题!!!
参数传递 参数传递,可以理解当我们要调用一个方法时,我们会把指定的数值,传递给方法中的参数,这样方法中的参数就拥有了这个指定的值,可以使用该值,在方法中运算了.这种传递方式,我们称为参数传递. 在这里 ...
- Java 常用类库一,main方法传参String[] args;获取输入Scanner ;hasNext();hasNextInt()
1. main方法传参 package com.zmd.common_class_libraries; /** 给mian方法传参测试 */ public class MainArgsTest { p ...
- 关于Java函数传参以及参数在函数内部改变的问题——JAVA值传递与引用最浅显的说明!
看了很多关于阐述JAVA传参到底是值传递还是引用的问题,有些说得很肤浅让人感觉似懂非懂的感觉,但是好像又能解决一些问题,然后就止步了.还有一些则是,讲得很深奥,看着好像很有道理的样子,但是其实还是没怎 ...
- javascript 字符串方法传参
javascript 字符串方法传参由于嵌套的单引号,双引号过多.有点混乱.. 正确方法如下: ' <td align="left"><input type= ...
- 对象引用 方法传参 值传递 引用传递 易错点 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
随机推荐
- Nuget 学习二
打包自己的类库 准备工作: 1)nuget 账号: https://www.nuget.org/ 2)nuget 包管理器 点击下载:NuGetPackageExplorer,安装完应该是酱紫. 开始 ...
- ssh爆破脚本
前些天,基友发我一个ssh爆破工具,看起来很吊的样子.然后我就无聊自己写了个py脚本的. 单线程:慢成狗----- #coding:utf-8 #author:jwong import threadi ...
- hibernate、easyui、struts2整合
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- openstack私有云布署实践【10.1 计算nova - kxcontroller节点配置(科兴环境)】
一.首先登录kxcontroller1创建kx_nova数据库,并赋于远程和本地访问的权限. mysql -u root -p CREATE DATABASE kx_nova; GRANT ...
- js的严格模式
严格模式: 严格模式这下的主要区别如下: 严格模式下的好处:
- 容易忘记的几个Linux命令
#查看文件或者目录的属性ls -ld filenamels -ld directory #vi编辑器输入:.,$d #清除全部内容 #修改管理员.用户密码passwd user #("use ...
- Python基础知识学习_Day3
一.字典用法 字典是一种key-value数据类型,通过key获取具体value的内容,字典的特性是无序.去重. 增删改查用法如下: 1.1基本增删改查操作 name = {"," ...
- UltraISO PE(软碟通) V9.5.5.2960 官方中文版
软件名称: UltraISO PE(软碟通)软件语言: 简体中文授权方式: 免费试用运行环境: Win7 / Vista / Win2003 / WinXP 软件大小: 1.9MB图片预览: 软件简介 ...
- php笔记(三)PHP类和对象之访问控制
访问控制通过关键字public,protected和private来实现.被定义为公有的类成员可以在任何地方被访问.被定义为受保护的类成员则可以被其自身以及其子类和父类访问.被定义为私有的类成员则只能 ...
- JS定时器设置、快速取消
1.首先定义自己的方法 function test() { alert("开始"); } 2.在定时器中使用 setInterval("test()",1000 ...