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 ...
随机推荐
- CentOs7.5安装FFmpeg
一.FFmpeg简介 FFmpeg是一个自由软件,可以运行音频和视频多种格式的录影.转换.流功能,包含了libavcodec ─这是一个用于多个项目中音频和视频的解码器库,以及libavformat— ...
- Maven下载Jar包(bat脚本)
1.创建一个bat文件叫download.bat 2.里面写入以下代码 call mvn -f pom.xml dependency:copy-dependencies 3.创建pom.xml文件 4 ...
- os.path.dirname(__file__)
os.path.dirname(__file__) 返回脚本的路径 描述: 必须实际存在的.py文件,如果直接在命令行执行,则会引发异常NameError: name 'file' is not de ...
- python 实现一个计算器功能
#s = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )' #第 ...
- 把大象装进冰箱:HTTP传输大文件的方法
上次我们谈到了HTTP报文里的div,知道了HTTP可以传输很多种类的数据,不仅是文本,也能传输图片,音频和视频. 早期互联网上传输的基本上都是只有几k大小的文本和小图片,现在的情况则大有不同.网 ...
- 《ASP.NET Core 高性能系列》致敬伟大的.NET斗士甲骨文!
写在开始 三年前,曾写过一篇文章:从.NET和Java之争谈IT这个行业,当时遭到某些自认为懂得java就了不起的Javaer抨击, 现在可以致敬伟大的.NET斗士甲骨文了 (JDK8以上都需要收费, ...
- tomcat问题解决
tomcat问题解决 运行tomcat环境下,idea中出现 error running 项目名address localhost1099 is already in use 的时候,如何解决? 1, ...
- Python趣用—配平化学方程式
不知不觉已经毕业多年了,不知道大家是否还记得怎么配平化学方程式呢?反正小编我是已经记不太清了,所以今天的文章除了分享如何用python配平化学方程式,顺带着还会复习 一些化学方程式的知识,希望广大化学 ...
- Spring 注解编程之 AnnotationMetadata
在上篇文章 Spring 注解编程之模式注解 中我们讲到 Spring 模式注解底层原理,依靠 AnnotationMetadata 接口判断是否存在指定元注解. 这篇文章我们主要深入 Annotat ...
- 100天搞定机器学习|Day8 逻辑回归的数学原理
机器学习100天|Day1数据预处理 100天搞定机器学习|Day2简单线性回归分析 100天搞定机器学习|Day3多元线性回归 100天搞定机器学习|Day4-6 逻辑回归 100天搞定机器学习|D ...