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 ...
随机推荐
- RT-Thread定时器以及结构体指针的一些思考
定时器分为软件定时器和硬件定时器.顾名思义,软件定时器就是有操作系统提供的软件定时器,硬件定时器就是用硬件芯片提供的定时器. 而在RT-Thread操作系统提供的定时器是软件定时器,但是为了便于管理, ...
- os.path.join路径拼接的问题
问题一: import os a = os.path.join("/test1", "/test2") print(a) b = os.path.join(&q ...
- 事务的隔离级别,mysql默认的隔离级别是什么?
读未提交(Read uncommitted),一个事务可以读取另一个未提交事务的数据,最低级别,任何情况都无法保证. (1)所有事务都可以看到其他未提交事务的执行结果 (2)本隔离级别很少用于实际应用 ...
- kuangbin专题 专题一 简单搜索 Find a way HDU - 2612
题目链接:https://vjudge.net/problem/HDU-2612 题意:‘@’表示KTV,‘#’表示无法走的地方,‘Y’,'M’表示两个人,他们要在KTV见面,问他们都到达KTV要花费 ...
- 解决Tomcat catalina.out 不断膨胀,导致磁盘占用过大的问题
到服务器上看了一下任务中心的日志情况,膨胀的很快,必须采取措施限制其增长速度. 我们采用Cronlog组件对此进行日志切分,官网http://cronolog.org/一直未能打开,只能从其它地方寻找 ...
- 剑指offer第二版-2.实现单例模式
面试题2:实现单例模式 题目要求: 设计一个类,只能生成该类的一个实例. /** * 单例模式 * 定义:指实现了特殊模式的类,该类仅能被实例化一次,产生唯一的一个对象 * 应用举例:windows的 ...
- 【POJ - 1190】生日蛋糕 (dfs+剪枝)
Descriptions: 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1 <= i <= M)层蛋糕是半径为 ...
- 乘法口诀表(C语言实现)
输出乘法口诀表,关键在于利用好循环语句,而且是二层循环.
- android_onSaveInstanceState_onRestoreInstanceState研究
当一个activity的状态是一个容易被系统宰掉时,比如pause或者stop状态,此时这个活动不一定已经被销毁了,那么这个activity的onSaveInstanceState方法会被系统调用(值 ...
- JavaScript函数及闭包
前面一片文章讲到过一点函数,了解到每声明一个函数就会产生一个作用域.而外面的作用域访问不了里面的作用域(把里面的变量和函数隐藏起来),而里面的可以访问到外面的.对于隐藏变量和函数是一个非常有用的技术. ...