Java没有引用传递只有按值传递,没有引用传递只有按值传递,值传递。

通过下面代码解释:

 public class Test {
public static void main(String[] args ){
int var = 1 ;
f(var) ;
System.out.println(var) ;
}
public static void f(int newVar ){
newVar = 2 ;
}
}

执行结果:

1

分析:

当执行 int var = 1 时,jvm在栈中开辟一块空间存放值---1,同时var变量指向值1所对应的内存空间,也就是var变量也有自己的内存空间,不过它的空间里存放的是值1所对应的内存地址。

当执行到第七行,要将var的值传递进方法f中时,jvm执行的操作是创建一个新的变量newVar,并将var里存放的值(也就是值1的内存地址)复制一份给newVar。

当执行到第八行时,jvm重新开辟值--2所对应的存储空间来存储值2,并修改了newVar里存放的地址值。

方法返回,执行到第五行,输出var所指向的值,当然是值1,因为var中的地址值根本没有变化。

上面示例用的是int,一个基本数据类型,对于引用数据类型同样适用,因为java中没有引用传递,只有值传递。例如自定义的类UserClass:

 class MyClass {
int var1 ;
}
public class Test {
public static void main(String[] args ){
MyClass myClass = new MyClass() ;
myClass.var1 = 1 ;
f(myClass) ;
System.out.println(myClass.var1) ;
}
public static void f(MyClass newMyClass ){
myClass.var1 = 100 ;
}
}

执行结果:

100

分析:

第六行:在栈中创建一个变量指向在堆中创建的对象。关于堆中对象属性的存储可以理解为每创建一个对象就会在堆中分配一块内存空间给改对象,这块内存空间中记录了该对象属于哪个类,剩下就是存储该对象的属性值。

第七行修改对象属性值:

下面就是关键的第八行值的传递了,jvm会在栈中在开辟一块空间newMyClass,然后把myClass里的内容拷贝进newMyClass,这样在方法f中对newMyClass的修改就是对MyClass所对应内容的修改,因为newMyClass也是指向与myClass同样的一块内存空间。

第十二行中对newMyClass属性的修改同样会影响myClass所指的内容,因为他们俩指的是同一块内存空间。

最后方法返回myClass所指内容同样被修改。

下面说一个比较特殊的类----String,这是java中的一个特殊的引用类型,使用String传递时会发现在方法中修改不会影响到方法外的值,例如下面这段代码:

 public class Test {
public static void main(String[] args ){
String var = "Hello" ;
f(var) ;
System.out.println(var) ;
}
public static void f(String newVar ){
newVar = "World" ;
}
}

运行结果:

Hello

在分析这段代码之前需要知道String的底层是怎样实现的,其实String是通过char数组来完成其功能,简单的说String就是对char[]的一个封装。还要明白直接“字符串内容”和使用new String(“字符串内容”)效果是一样的,只不过jvm对这两种创建的字符串存储的地方不同而已。对上面这段代码的分析当然还要使用对引用数据传值方法分析。

第三行jvm在静态存储区存放创建的“Hello”字符串,并在栈中开辟var指向Hello的地址(var中存储的值是Hello字符串的地址)。当将var作为参数传递时,jvm会在栈中新创建一个变量newVar,这时newVar是指向"Hello"内存区的,但是在第八行 newVar = “World”却把newVar中存储的“Hello”地址改为一个新创建的“World”String对象的地址,注意,var内存储的地址仍然是“Hello”,所以在方法返回时输出的仍然是Hello。

终于写完了~~~ 发现自己想和写完全是两码事‘(*>﹏<*)′,其中一定有错误,在内存分配地方没有说清楚,因为我也不太清楚,还有就是关于对象中属性的内存分配,这个我真不知道,哪位知道别忘告诉我~~

java按值传递理解的更多相关文章

  1. java按值传递理解(转)

    ava没有引用传递只有按值传递,没有引用传递只有按值传递,值传递. 通过下面代码解释: 1 public class Test { 2 public static void main(String[] ...

  2. 转------深入理解--Java按值传递和按引用传递

    引言 最近刷牛客网上的题目时碰到不少有关Java按值传递和按引用传递的问题,这种题目就是坑呀,在做错了n次之后,查找了多方资料进行总结既可以让自己在总结中得到提高,又可以让其他人少走弯路.何乐而不为? ...

  3. JAVA 需要理解的重点 一

    需要理解的重点内容有: JVM内存管理机制和垃圾回收机制(基本每次面试都会问,一定要搞得透彻) JVM内存调优(了解是怎么回事,一般做项目过程中使用较多) 设计模式(熟悉常见设计模式的应用场景,会画类 ...

  4. [java] 深入理解内部类: inner-classes

    [java] 深入理解内部类: inner-classes // */ // ]]>   [java] 深入理解内部类: inner-classes Table of Contents 1 简介 ...

  5. Java初始化理解与总结 转载

    Java的初始化可以分为两个部分: (a)类的初始化 (b)对象的创建 一.类的初始化 1.1 概念介绍: 一个类(class)要被使用必须经过装载,连接,初始化这样的过程. 在装载阶段,类装载器会把 ...

  6. 从Java视角理解CPU上下文切换(Context Switch)

    从Java视角理解系统结构连载, 关注我的微博(链接)了解最新动态   在高性能编程时,经常接触到多线程. 起初我们的理解是, 多个线程并行地执行总比单个线程要快, 就像多个人一起干活总比一个人干要快 ...

  7. 从Java视角理解CPU缓存(CPU Cache)

    从Java视角理解系统结构连载, 关注我的微博(链接)了解最新动态众所周知, CPU是计算机的大脑, 它负责执行程序的指令; 内存负责存数据, 包括程序自身数据. 同样大家都知道, 内存比CPU慢很多 ...

  8. Java IO 理解流的概念

    Java IO 理解流的概念 @author ixenos 在理解流时首先理解以下概念 1.流的来源和去向一般在构造器指出 2.方法中的形参一般是将流输出到某个位置,读取(INPUT)流从流读出数据( ...

  9. Effective Java通俗理解(持续更新)

    这篇博客是Java经典书籍<Effective Java(第二版)>的读书笔记,此书共有78条关于编写高质量Java代码的建议,我会试着逐一对其进行更为通俗易懂地讲解,故此篇博客的更新大约 ...

随机推荐

  1. css 强制 中文、英文 换行

    .livechat-text a { display: block; word-break:break-all; /* 英文换行 */ white-space:normal; /* 中文换行 */ } ...

  2. jQuery如何判断元素是否是隐藏的?

    jQuery函数简介: is(expr) 用一个表达式来检查当前选择的元素集合,如果其中至少有一个元素符合这个给定的表达式就返回true. 如果没有元素符合,或者表达式无效,都返回'false'. 注 ...

  3. nth-of-type

    ul li{ height:53px; line-height:53px; border-top:1px solid #e5e5e5;  display:block;color:#444;     } ...

  4. iOS开发——高级篇——通讯录

    一.简介 1.如何访问用户的通讯录1)在iOS9之前有2个框架可以访问用户的通讯录AddressBookUI.framework提供了联系人列表界面.联系人详情界面.添加联系人界面等一般用于选择联系人 ...

  5. 实现统一用户体验的BaseActivity

    对一个规模较大的App开发团队来说,保持统一的代码规范是个好的事情,同时,保持统一的用户体验规范也是个好的事情. 当用户进入一个页面时,一般会有以下交互场景:场景1, 初始化loading,页面从se ...

  6. C# FromBase64String 解码换行问题

    Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045-RFC2049,上面有MIME的详细规范.Base64编码可用于在HTTP环境下传递较长的标识信息.例如 ...

  7. CCProxy二级代理上网设置

    假如电脑A可以通过代理服务器上网,B电脑又可以连接A电脑,那么A电脑可以作为二级代理服务器进行上网,需要设置如下: 1.在A电脑上安装CCProxy,以v8.0为例 2.选择设置->高级 3.启 ...

  8. PHP 面向对象

    封装与不封装的区别:   未封装 时 外部随意更改数据   数据 不需要判定 就可以执行    外部直接操作数据 封装:  外部同样可以对数据更改,但需要 调用  类里面的  函数  外部间接操作数据 ...

  9. yii 常用的多表查询

    return $this->model()->getDbConnection()->createCommand() ->select("t.type,t.title, ...

  10. MFC中CListCtrl控件的使用方法

    定义一个派生类CViewList 派生于CListCtrl 在要包含该控件的类(CView)中定义一个CViewList类型的变量 CViewList m_wndListView; 在CView响应的 ...