java学习笔记2-平台无关性与值依赖
前言
-
本人笔记,仅作学习使用
-
参考博客以及相关学习视频
Java工程师成神之路-http://hollischuang.gitee.io/tobetopjavaer/#/basics/object-oriented/java-pass-by
按值传递、按引用传递、按共享传递-https://www.cnblogs.com/lmjZone/p/7977844.html
java平台无关性-由Java代码规范、Class文件、JVM等支持
1. 什么是平台无关性?
平台无关性就是一种语言在计算机上的运行不受平台的约束,一次编译,到处执行(Write Once ,Run Anywhere)
2. 平台无关性有什么好处?
- java程序可以在任意设备上运行
- 对于Java开发者来说,Java减少了开发和部署到多个平台的成本和时间
3. Java平台无关性的实现
1)前提--编译基础
- 设备执行Java程序需先将其转换成设备可识别的二进制,这个过程就是编译
- 编译可分为前端编译和后端编译
- 前端编译将Java程序转换成Class文件,后端编译将Class文件转换成机器可执行的二进制文件
2)JVM--java虚拟机
- 前面说到编译,在Java中,前端编译是通过编译器javac或者eclipse、idea自带的编译器来实现的;后端编译则通过JVM来实现
- 所以说,Java虚拟机充当了桥梁,扮演了运行时Java程序与其下的硬件和操作系统之间的缓冲角色
- 值得注意的是,JVM是平台有关的,Java的平台无关性是建立在JVM的平台有关性上的
3)Class文件--字节码文件
- Java虚拟机只与由字节码组成的Class文件进行交互。
- 各种不同的平台的虚拟机都使用统一的程序存储格式——字节码(ByteCode)是构成平台无关性的另一个基石
- 因为Java Class文件可以在任何平台创建,也可以被任何平台的Java虚拟机装载并执行,所以才有了Java的平台无关性
4)Java语言规范
- Java语言在跨平台方面也是做了一些努力的,这些努力被定义在Java语言规范中。
- 通过保证基本数据类型在所有平台的一致性,Java语言为平台无关性提供强了有力的支持。
值传递
1. 前提--程序语言中的形参和实参
- 形式参数:是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。
- 实际参数:在调用有参函数时,主调函数和被调函数之间有数据传递关系。在主调函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”。
- 例子:
public static void main(String[] args) {
ParamTest pt = new ParamTest();
pt.sout("Hollis");//实际参数为 Hollis
}
public void sout(String name) { //形式参数为 name
System.out.println(name);
}
2. 值传递、引用传递、共享传递
值传递(pass by value):是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递(pass by reference):是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。(引用指内存地址)
共享对象传递:共享传递实际上就是值传递的一个特例,原理与值传递相同,它特殊的地方在于,它将引用当作值传递过去,可以说是传递引用
3. 迷糊点:共享对象传递传的是引用,这不就是引用传递吗??
-
其实这是不对的。我们先来说说值传递和引用传递的区别
-
如图所示,值传递是会创建副本的,而共享对象传递是值传递的一个特例,它也会创建一个副本
-
而 创建副本 就是 引用传递 和 共享对象传递 的根本区别
-
举例:
function foo(num1, obj1){
...
}
main(){
var num=10,
var obj={value:'hello'};
foo(num, obj);
}
-
如上图所示,引用传递没有创建副本,obj和obj1是同一个引用;而共享对象传递有创建副本,obj和obj1在内存中不是同一个
-
如果还是区分不出两者的话,我再加点细节
符号引用,指的是“obj1”,"obj",或者是任何形式的字面量,它是一种唯一符号,
唯一性的存在可以保证JVM编译时可以通过符号引用(如obj1)找到那个引用类的地址,即地址XXX,而这个就是直接引用直接引用,就是实例在堆中的地址,即地址XXX
-
如果是引用传递的话。obj本身是地址xxx指向实例a,引用传递后,obj1的符号引用跟obj一样(即代表obj1和obj在栈内存中属于同一位置),同样也是地址xxx指向实例a。
现在修改obj1的值让它指向实例b,显然obj也指向了实例b
-
如果是共享对象传递的话,obj本身是地址xxx指向实例a,共享传递后,obj1的符号引号跟obj不一样(即代表obj1和obj在栈内存中不属于同一位置,即代表obj1在栈中的新位置拷贝了一份地址xxx),同样也是地址xxx指向实例a。
现在修改obj1的值让它指向实例b,显然,obj仍旧指向实例a。而这一点就是传递引用和共享引用的根本区别
-
4. 为什么说Java中只有值传递
- Java中的值用值传递,而引用都是用按共享传递的,按共享传递是值传递的一个特例,所以说Java中只有值传递