转:JAVA 参数传递
转自:http://blog.sina.com.cn/s/blog_5dd380b90100bvel.html
网络上有太多关于JAVA参数传递是传值还是传引用的讨论,其实大多是概念不清,混淆视听。从程序运行的角度来看,参数传递,只有传值,从不传递其它的东西。只不过值的内容有可能是数据,也有可能是一个内存地址。
Java中的数据类型有两大类,即基本类型(primitive types), 共有8种,包括int, short, long, byte, float, double, boolean, char,存在于栈(Stack)中。另一种暂称为对象类型,包括Integer, String, Double等相应基本数据类型的包装类,以及其他所有JAVA自带和用户自定义的类,这些类数据全部存在于堆中(Heap),如下图所示。
对象类型的数据不同于基本类型的数据,我们所定义的对象变量并不是对象实例本身,而是对象的一个引用(reference)地址,该内存地址 用来定位该对象实例在HEAP中的位置。对象实例本身和对象的引用分别保存在HEAP和STACK中,对象引用和对象实例之间的关系好比遥控器和电视机之 间的关系,在房间走动的时候里,你只需拿着遥控器就可以控制电视机,而不必带着电视机。而且,即使没有电视机,遥控器也可以独立存在,也就是说你可以定义 一个对象类型的变量,但是可以暂时不和一个对象实例关联。多个对象引用也可以指向同一个对象实例。
| Heap(堆) | Stack(栈) | |
| JVM中的功能 | 内存数据区 | 内存指令区 |
| 存储数据 | 对象实例 | 基本数据类型, 指令代码,常量,对象的引用地址 |
下面我们来看看几个例子,您就会更加明白。
例子1:
public class Test {
public static void changeValue(int i) {
i=2;
System.out.println("during test: i = " + i);
}
public static void main(String[] args) {
int i = 1;
System.out.println("Before test: i = " + i);
changeValue(i);
System.out.println("After test: i = " + i);
}
}
运行结果:
Before test: i = 1
during test: i = 2
After test: i = 1
不难看出,虽然在 changeValue(int
i)方法中改变了传进来的参数的值,但对这个参数源变量本身并没有影响。其内部原理是,main方法里的变量和changeValue方法的参数是两个不
同的变量,以参数形式传递简单类型的变量时,实际上是将参数的值作了一个拷贝传进方法的,那么在方法里再怎么改变其值,其结果都是只改变了拷贝的值,而不
是源值。
例子2:
public class Test {
public static void test(StringBuffer str) {
str.append(", World!");
}
public static void main(String[] args) {
StringBuffer string = new StringBuffer("Hello");
test(string);
System.out.println(string);
}
}
运行结果:
Hello, World!
在这个例子里,似乎变量string被“改变”了。但其实改变的并不是string变量本身,也就是说string保存的内存地址并没有被改变,改变的是
它所指向的对象实例。内部原理是这样的,在main方法里定义了一个对象引用string,并且把它和一个对象实例关联new
StringBuffer。方法调用的时候,string所保存的对象实例的内存地址传递给了test方法的对象引用参数str,这时就有两个对象引用变
量指向同一个对象实例。这两个对象引用都可以对该对象实例进行操作,操作结果都有效,因此在test方法执行完之后,对象实例的内容已经被改变了,这个时
候再通过main方法里的string引用去查看对象实例的内容,看到的就是改变之后的内容。
例子3:
public class Test {
public static void test(String str) {
str = "World";
}
public static void main(String[] args) {
String string = "Hello";
test(string);
System.out.println(string);
}
}
运行结果:
Hello。
这个结果和上面结果矛盾吗?一点也不矛盾。在这个例子中,参数传递过程和上个例子完全一样,但是在test方法里并不是对原来指向的对象实例进行操作,而是把str指向了另外一个对象实例,当然对原来的对象实例毫无影响。
转:JAVA 参数传递的更多相关文章
- Java 参数传递都是值传递
Java 参数传递都是值传递,验证代码如下 public class ParamTransferTest { public static void swap(int a, int b) { int t ...
- java参数传递时到底是值传递还是引用传递
java参数传递时到底是值传递还是引用传递(baidu搜集) 问”,很多人的BLOG里都引用这些面试题,最近因为工作内容比较枯燥,也来看看这些试题以调节一下口味,其中有一道题让我很费解. 原题是:当一 ...
- 图解JAVA参数传递
今天做项目,发现了一个问题,当String作为参数传递的时候,在函数内部改变值对外部的变量值无影响,如下代码: public static void main(String[] args) { Str ...
- JAVA学习笔记之图解JAVA参数传递
今天做项目,发现了一个问题,当String作为参数传递的时候,在函数内部改变值对外部的变量值无影响,如下代码: public static void main(String[] args) { Str ...
- 浅谈Java参数传递机制
Java参数传递 才疏学浅,今天才知道Java中方法的参数是可以传递对象引用进去的. Java的参数传递机制很简单,其实就是值传递. 所谓值传递,也就是我们在给方法传递一个参数的时,传递的 ...
- java 参数传递是引用传递还是值传递?
JAVA的参数传递倒底是值传递还是引用传递,我觉得两种说法都没错,关键是看怎么理解“引用”和“引用传递”. (一)从编译原理的角度讲,所有那些无法通过形参来修改实参本身的传递机制都是“值传递”,在JA ...
- 【转】java参数传递(超经典)
原文网址:http://blog.sina.com.cn/s/blog_4b622a8e0100c1bo.html Java中的参数传递机制一直以来大家都争论不休,究竟是“传值”还是“传址(传引用)” ...
- java 参数传递
由一个问题来引入参数传递的问题 public static void main(String[] args) { int x=1; int[] y =new int[10]; m(x,y); Syst ...
- java参数传递(值传递还是引用传递)
Java中的参数传递机制一直以来大家都争论不休,究竟是“传值”还是“传址(传引用)”,争论的双方各执一词,互不相让.不但“菜鸟”们一头雾水,一些“老鸟”也只知道结果却说不出所以然来.我相信看过下面的内 ...
随机推荐
- python+API接口测试框架设计(unittest)
1.测试框架简介 整个接口测试框架的设计图如下: basepage:存放的是公共的方法 common:存放的是自定义工具 data:存放的是公共动态数据,如BB.xls/ Id.md log:存放的是 ...
- xshell工具使用
一.下载安装 参考见:https://www.bilibili.com/video/BV1hh411k7vy?from=search&seid=2244124597826079746 流程: ...
- Spring 学习笔记(2) Spring Bean
一.IoC 容器 IoC 容器是 Spring 的核心,Spring 通过 IoC 容器来管理对象的实例化和初始化(这些对象就是 Spring Bean),以及对象从创建到销毁的整个生命周期.也就是管 ...
- Splay与FHQ-Treap
两个一起学的,就放一块了. 主要是用来存板子. Splay //This is a Splay Tree. #include <cstdio> #include <cstring&g ...
- 数据结构与算法(python版)
ADT抽象数据类型(ADT:Abstract Data Type):ADT是对数据进行处理的一种逻辑描述,并不涉及如何实现这些处理. 同一ADT可以采用不同的数据结构来实现:1.采用程序设计语言的控制 ...
- Flask 之db 配置坑
文件 .flaskenv中 DATABASE_URI = 'mysql://username:password@server/db' flask db init 报错 ImportError: No ...
- 自动部署Springboot项目脚本小脚本
#!/bin/bash echo '自动部署Springboot项目脚本...' # aaa.jar 项目jar包 pid=`ps -ef|grep aaa.jar|grep -v grep|grep ...
- Upload-labs 文件上传靶场通关攻略(上)
Upload-labs 文件上传靶场通关攻略(上) 文件上传是Web网页中常见的功能之一,通常情况下恶意的文件上传,会形成漏洞. 逻辑是这样的:用户通过上传点上传了恶意文件,通过服务器的校验后保存到指 ...
- 天梯赛 L2-008 最长对称子串
题目是PTA的天梯赛练习集中的L2-008 https://pintia.cn/problem-sets/994805046380707840/problems/994805067704549376 ...
- 通信协议,TCP/UDP对比:
通信协议 协议:约定,比如在中国约定说普通话 网络通信协议:速率,传输码率,代码结构,传输控制... 问题:非常复杂 大事化小:分层 TCP/IP协议簇:实际上是一组协议 重要: TCP:用户传输协议 ...