不同于CPP,JAVA中不需要程序员对指针进行操作。不过,这不代表JAVA没有指针,事实上,JAVA的指针操作都被底层代码封装了。笔者在初学Java时,虽然就了解了形参,实参,StringBuffer这些概念,但一直只流于表面,对此没有一个深度的认识。直到最近开始学习JVM虚拟机,才真正认识到了JAVA的精妙之处。

  首先,先说结论,Java中所有的基本数据类型的传递,都是按值传递,即传递的都是形参。除此以外的其他任何传递都是按地址传递,传递过去的都是实参,即cpp概念中的引用传递。最初笔者学习时也是就看到这,虽然知道了结论,但由于概念过于抽象,始终无法理解其本源(或者说内存模型中到底发生了什么)。Talk is cheap,show me the code。下面,我们来看一段代码。

package point;

public class Formal {
private void formal(int p){
p=p*5;
System.out.println(p);
} public static void main(String[]args){
int i=5;
Formal fromal=new Formal();
fromal.formal(i);
System.out.println(i);
}
}

  这段代码在控制台输出的结果是25和5,很显然,按照正常的逻辑来说的话应该是25,25才对。为什么会出现这种结果?事实上,Java中对基本数据类型的传递都是值传递(不清楚为什么这样,笔者的理解是基本数据类型在内存中的组合是有限的,这样内存可以知道你需要传递的是什么,换而言之,它可以真正理解你要传递的东西,因此可以复制一份进行传递,这样虽然会增大程序员的学习成本,但可以节省内存或者是增进效率。而非基本数据类型因为变化太多了,所以无法这么操作。不知道本人的理解有没有误差,才疏学浅,希望大神们多多指正)。通俗一点说,就是复制操作,在内存中,JVM只是把你操作的数据复制了一份给你传递到的对象,而不是把它本身传递了过去。

  这里要说一个特例,String类,贴一段代码。

package point;

public class ActualString {
private void actual(String color){
color=color+" is red";
System.out.println(color);
} public static void main(String[]args){
String car="myCar";
ActualString actualString =new ActualString();
actualString.actual(car);
System.out.println(car);
}
}

  这里控制台输出结果是myCar is red,myCar,这不代表String传递的也是形参,或者是String是基本数据类型,事实上因为String类都是被final关键字修饰的,所以它的值不会变化,所以,字符串拼接之类的操作事实上只是在内存中开辟了一个新的空间,而原有的空间其实还存在,所以这就是为什么字符串的操作要使用StringBuffer类。

  下面我们看一下实参的代码。

package point;

public class Actual {
private void actual(int arr[]){
arr[0]=arr[0]*5;
System.out.println(arr[0]);
} public static void main(String[]args){
int a[]=new int[]{5};
Actual actual=new Actual();
actual.actual(a);
System.out.println(a[0]);
}
}

  毫无疑问,这次控制台输出的结果是25,25。这里传递的就是对象本身的地址值,即实参,可以理解为剪切操作,将自身传递过去。

  

package point;

class Variable{
public static Variable VAR=null; public int i; protected void a(int p){
p=p*5;
System.out.println(p);
} public Variable(){
i=5;
Variable.VAR=this;
} } public class FormalInActual {
public static void main(String[] args){
Variable variable=new Variable();
System.out.println(variable.i);
variable.a(variable.VAR.i);
System.out.println(variable.VAR.i);
} }

  输出结果是5,25,5。即使是像这样把基本数据类型写进方法里,通过方法传递,其传递的依旧是形参。

最新文章

  1. 基于bootstrap 的datatable插件的使用(php版)
  2. HashTree(哈希树) ——和trie类似,只是将字符换成了质数,sphinx用到了???
  3. 查看Linux系统版本信息
  4. PHP 图片文件上传代码
  5. linux下安装多个mysql实例(摘自国外:How to create multiple mysql instance in CentOS 6.4 and Red Hat 6.4)
  6. 使用gdb跟踪Linux内核启动过程(从start_kernel到init进程启动)
  7. leetcode_question_64 Minimum Path Sum
  8. BZOJ3202 [Sdoi2013]项链
  9. web端常见安全漏洞测试结果分析-- appscan
  10. 使用ftp软件上传下载php文件时换行丢失bug(全部变为一行)
  11. 一个巨low的“2048”
  12. 三种Tomcat集群方式的优缺点分析
  13. Intervals POJ - 3680 (MCMF)
  14. php的pid文件指定用户
  15. (后端)excel设置日期格式的步骤
  16. Commonjs、AMD、CMD
  17. Java面试题大汇总
  18. javascript 1.5s跳转
  19. UUID的定义以及作用
  20. 转载【linux】Linux学习之CentOS6.x+7.x---网卡的配置

热门文章

  1. c++存储区域
  2. mind map 思维导图
  3. Java核心API需要掌握的程度
  4. array_multisort 对关联数组进行排序的问题 PHP
  5. java有参
  6. PYTHON __main__
  7. 编程练习 将一个字符串中的空格替换为 "%20"
  8. C++面试常见问题——16函数模板的使用
  9. 洛谷 P3435 [POI2006]OKR-Periods of Words
  10. R box-cox变换 《回归分析与线性统计模型》page100