Java中只有值传递,(及值传递与引用传递详解)
首先呢,我们来说一下值传递与引用传递的区别(这两个玩意儿实在调用函数的时候提到的)
比如说
code( a)
code( int a )
code(a)是调用函数,a是我们原本函数的一个值类型,然后使用code函数,把他作为一个参数传入。
code(int a ) 这里注意哦,这个a和我们上面那个a不一样哦,在我们调用这个函数的时候呢,首先会在我们的栈内存里
将这块代码入栈(代码的执行实际上就是一个入栈出栈的样子)此时这个函数会初始化一块内存用来存放上一级函数传的a的值,
比如说我们调用函数a 是a1,被调用函数a是a2,实际上,这个a2在函数入栈的过程中被初始化为0值,然后才会执行一个 a2 =a1的操作
实际上就是把a2的那块内存变的和a1的那块内存一模一样的过程(拷贝),这样就是传值啦,简单点说的话,就是我传给你一个参数,但是这个参数是我的,你得自己再建一个你自己的,然后把它弄的和我的一模一样。这就是传值。(我的是我的,你的是你的,你不能拿我的,但是你可以自己搞一个赝品)
public class Test1 {
public static void main(String[] args) {
int a1 = 5;
print(a1);
System.out.println(a1);
}
private static void print(int a2) {
a2 -=5;
System.out.println(a2);
}
}
输出结果:
0
5
对a2操作不影响a1,这就是值传递
引用传递:
其实呢,在我的认知里吧,引用传递是就相当于,我有一个东西,然后,我要给你用,你可以对这个东西进行操作,在本质上来说其实就只有一个东西。你对它的操作,就直接改变它的本身了。(因为Java里面没有引用传递,所以我用Go语言写一下。)
package main
import "fmt"
func main(){
var a int = 10
printnum(&a)
fmt.Println(a)
}
func printnum( a *int){
*a -= 5
fmt.Println(*a)
}
输出结果:
5
5
这里说明一下指针的概念,指针其实也是一种变量类型,比如我们上面的(*int)类型。
我们首先是在我们的主函数里创建啊a1 int类型,随后我们调用了printnum(a2 *int)这个方法,
而我们传入的参数是&a1,这个&符号,和*是搭配使用的,&符号可以返回一个指向这个变量的指针类型的变量。
而这个指针类型的变量内存中存储的实际上它指向的那个变量的内存地址,然后a2其实也就是将这个内存地址拷贝了一份(像上面的那个值传递一样,我传给你的不是你的,是要你复制的),此时a2(*int类型)内存里存储的就与&a1返回的指针存储的相同,也就是a1的内存地址然后我们就可以调用*a2来操作a1啦。(对于这个*符号啊,我简单介绍一下,其实它相当于通过a2的内存存储的地址而找到这个地址所待变的内存位置所存储的信息,也就是那个a1,因为a2里边存储的是a1的内存地址,*a2就是找到a2存储的地址所代表的那个内存位置所存储的信息,就是 *a2 == a1 )
通过传递一个变量的指针(内存地址),而使得另一个函数也可以操作这个变量。实际上操纵的是一个变量。
(我这里有个东西,你可以用,但是你不知道我这个东西的位置(地址),所以我就要给你发个消息(存储地址的指针)告诉你这个东西在哪儿,你收到消息以后,拆开消息看看,就可以找到了)
以上就是值传递和指针传递的详解啦,
说白了他们的区别就是,值传递操作的是不同的对象,引用传递操作的是同一个对象。但是实际上引用传递内部使用的值传递,想一想,在我们程序运行过程中的那个指针,是值传递过去的(也就是,它拷贝的一份,是两个不同的指针哦,这个概念搞通)
接下来我们来说一下,Java中的值传递。
首先需要说明一下,值传递和引用传递,这是传递的方式哈(这是传递方式)
然后值类型和引用类型。和上面那两个可不一样哈。(别懵了)(这是存储方式)
首先呢,Java里有两种存储类型,值类型和引用类型
我们之前不是说Java中运行函数的时候都在栈内存储的嘛。
所有的变量也是在栈内。
值类型、引用类型的变量也都是在栈内存储,不过存储的东西不一样
值类型内部存储的就是值
比如说 int a = 10 这个a的内存存储的就是10的二进制数
而 Student std = new Strudnt()这个std的内存中存储的则是一个student对象的内存地址,而这个student对象在堆(内存的另一个区域。。咳咳咳,堆栈是两个区域)内存着。
然后这个就是引用类型,是不是特别像我们Go里的指针,但是我们Java里面可是不支持指针操作的,可别搞混了。
然后呢,我们该讨论值类型和引用类型在值传递方式的不同了。
下面的一定要看懂。我会尽量。
首先值类型的值传递就不说了,它就是普通的值传递,就是拷贝一份过去了。
引用类型的值传递的话。你们想啊首先我们栈内存储的是那个对象的内存地址对吧,
然后,我们的值传递是把栈内存的变量拷贝一份对吧,所以其实我们拷贝过去的变量存储的其实是堆内存中对象的内存地址。
所以我们的引用传递实际上操作的是同一个对象。虽然我们Java不支持引用传递,但实际上引用类型的值传递本身和引用传递的方式差距不大。拷贝指针拷贝的是地址,拷贝引用类型变量也是拷贝的地址。不过差距就是人家引用传递是可以无限的来回套指针的。。。而引用类型就是一个。。其实差距不大,这就是我为什么要说引用传递内部包含的值传递。
Java中只有值传递,(及值传递与引用传递详解)的更多相关文章
- java中4种修饰符访问权限的区别及详解全过程
java中4种修饰符访问权限的区别及详解全过程 http://jingyan.baidu.com/article/fedf0737700b3335ac8977ca.html java中4中修饰符分别为 ...
- java中String、包装类、枚举类的引用传递
一般情况下,我们认为Java中了除了八种基本数据类型,其他都是对象,进行引用传递: 但是:String.包装类.枚举类作为参数传递后发现,没有达到引用传递的效果,很多人认为它是值传递! 首先,对象肯定 ...
- java中String s="abc"及String s=new String("abc")详解
1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取速度比堆要快,仅次于直 ...
- java中的Static、final、Static final各种用法详解
前言 对Static.final.Static final这几个关键词熟悉又陌生?想说却又不知怎么准确说出口?好的,本篇博客文章将简短概要出他们之间的各自的使用,希望各位要是被你的面试官问到了,也能从 ...
- JAVA中使用log4j及slf4j进行日志输出的方法详解
JAVA中输出日志比较常用的是log4j,这里讲下log4j的配置和使用方法,以及slf4j的使用方法. 一.下载log4j的架包,并导入项目中,如下: 二.创建log4j.properties配置 ...
- java中的静态变量,静态方法与静态代码块详解
java中的类的生命周期分为装载,连接,初始化,使用,和卸载五个过程. 而静态代码在类的初始化阶段被初始化. 而非静态代码则在类的使用阶段(也就是实例化一个类的时候)才会被初始化. 静态变量 可以将静 ...
- java中的ArrayList 、List、LinkedList、Collection关系详解
一.基础介绍(Set.List.Map) Set(集):集合中的元素不按特定方式排序,并且没有重复对象.他的有些实现类能对集合中的对象按特定方式排序. List(列表):集合中的元素按索引位置排序,可 ...
- java中的静态变量、静态方法与静态代码块详解与初始化顺序
我们知道类的生命周期分为装载.连接.初始化.使用和卸载的五个过程.其中静态代码在类的初始化阶段被初始化. 而非静态代码则在类的使用阶段(也就是实例化一个类的时候)才会被初始化. 静态变量 可以将静 ...
- 关于JAVA中Byte类型的取值范围的推论(*零为正数,-128在计算机中的表示方法...)
先看一段推理<*一切都是在8个比特位的前提下,讨论二进制的符号位,溢出等等,才有意义*> +124:0111 1100 -124:1000 0100 +125:0111 1101 -125 ...
- JAVA中List对象去除重复值的方法
JAVA中List对象去除重复值,大致分为两种情况,一种是List<String>.List<Integer>这类,直接根据List中的值进行去重,另一种是List<Us ...
随机推荐
- NumPy基础操作(3)——代数运算和随机数
NumPy基础操作(3)--代数运算和随机数 (注:记得在文件开头导入import numpy as np) 目录: NumPy在矩阵运算中的应用 常用矩阵运算函数介绍 编程实现 利用NumPy生成随 ...
- 【Mysql】索引简介
本文口味:番茄炒蛋,预计阅读:10分钟. 博客又停更了两个月,在这期间,对人生和世界多了许多思考.在人生的不同阶段,会对生活和世界有着不一样的认知,而认知的改变也会直接反应在行为模式之中. 对于生活的 ...
- Docker笔记(二):Docker管理的对象
原文地址:http://blog.jboost.cn/2019/07/14/docker-2.html 在Docker笔记(一):什么是Docker中,我们提到了Docker管理的对象包含镜像.容器. ...
- 拓扑排序 (Topological Sorting)
拓扑排序(Topological Sorting) 一.拓扑排序 含义 构造AOV网络全部顶点的拓扑有序序列的运算称为拓扑排序(Topological Sorting). 在图论中,拓扑排序(Topo ...
- 用Python玩数据-笔记整理-第一章
第一个程序:print >>>print("Hallo World!") >>>Hallo World! mystring = "Ha ...
- thread学习笔记--BackgroundWorker 类
背景: 在 WinForms 中,有时要执行耗时的操作,比如统计某个磁盘分区的文件夹或者文件数目,如果分区很大或者文件过多的话,处理不好就会造成“假死”的情况,或者报“线程间操作无效”的异常,或者在该 ...
- Excel催化剂开源第26波-Excel离线生成二维码条形码
在中国特有环境下,二维码.条形码的使用场景非常广泛,因Excel本身就是一个非常不错的报表生成环境,若Excel上能够直接生成二维码.条形码,且是批量化操作的,直接一条龙从数据到报表都由Excel完成 ...
- Yarn工作机制
概述 (0)Mr 程序提交到客户端所在的节点. (1)Yarnrunner 向 Resourcemanager 申请一个 Application. (2)rm将该应用程序的资源路径和Applicati ...
- [leetcode] 110. Balanced Binary Tree (easy)
原题链接 水题 深度搜索每一节点的左右深度,左右深度差大于1就返回false. class Solution { public: bool isBalanced(TreeNode *root) { b ...
- WGAN的改进点和实操
包含三部分:1.WGAN改进点 2.代码修改 3.训练心得 一.WGAN的改进部分: 判别器最后一层去掉sigmoid (相当于最后一层做了一个y = x的激活) 生成器和判别器的loss不 ...