- 浏览: 1062119 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (399)
- C++ (39)
- Java (74)
- Java界面开发学习笔记 (4)
- Java用户的c++之旅 (0)
- 自言自语 (12)
- DSP (1)
- MCU (0)
- CG (0)
- Jabber (0)
- Gloox (0)
- Linux (11)
- Windows (19)
- Networks (4)
- Jobs (0)
- PHP (1)
- JSP (2)
- 生活 (35)
- C (2)
- Qt4 (2)
- C# (50)
- WPF (5)
- ASP (2)
- FLEX (47)
- SQL (20)
- JavaScript (12)
- SharePoint (6)
- GWT (1)
- Dojo (9)
- HTML (11)
- Others (7)
- 如何安装配置系列 (7)
- UML (2)
- Android (3)
- alibaba (1)
最新评论
-
zxjlwt:
学习了http://surenpi.com
Firefox插件开发: Hello World! -
ylldzz:
楼主知道MVEL怎么调试么
MVEL简介及快速使用 -
blueman2012:
您好,可否提供源码下载,我把您的代码贴过来后,好多报错的,谢谢 ...
Log4J日志解析 -
svygh123:
你的游标都没有关闭呢!
MYSQL游标嵌套循环示例 -
dizh:
写的很好啊
MVEL简介及快速使用
这是个老生常谈的问题了,经过了先辈们无数的争论,但是还是没有提出一个令所有人满意的答案。当然,我在这里只是就我自己对Java和其他语言的一些认识谈谈自己的理解和看法。
首先,我们要明确下面这两条不可争论的事实了:
【1】、对象是传引用的
【2】、基本类型是传值的
我对这个问题是这样理解的:
有过C++背景的朋友可能都会有一个认识,因为C/C++传参有很多种选择,直接传递对象或值,或者传递指针,传递引用等。而大家都有个共识,那就是在传递基本数据类型时,选择第一种,而传递对象的时候则选用传指针或者引用。这点可以从数据传输效率的角度上得到解释。
而Java创始人James在某些方面还是得借鉴一些C的思想的,所以上述两条就比较好理解了。
个人对传参的理解是:
函数参数相对其他字段,在编译器里肯定会有特殊处理的,而一般的编译器则是这样处理:
在运行栈中拷贝一份传递过来的参数(值参),而后面函数体的关于值参的操作实际上都是针对运行栈里保存的备份操作的。可以用这种理解验证一下C++的三种情况。例如传递过来的是引用,则编译器的处理流程是这样的:
首先拷贝传递来的值参(注意:值参也是引用,Java里new之后获得的都是对象的引用,而不是对象本身,这点和c++很不同),然后将其压入运行栈,后面的操作也就是对这份拷贝(也是对预期的对象的引用,所以可以到达对象)操作了。
我们看看以下的几个例子来增加对上述思想的理解。
Example1:
运行结果:
---------SWAP UNABLE----------
Int1 is 10
Int2 is 50
我们都知道一点:void swap(int, int)是不能达到交换两个参数的值的。我们这里试试使用Integer对象呢?同样也交换失败,原因很简单:void swap(Integer para1, Integer para2)函数传递进来的是两个类型为Integer类的引用,而在函数体里实现的功能只是改变了para1和para2引用的对象,而para1和para2在内存中的值却一点变化都没有。可能这样理解更加形象一点:
例如,A省省长是小王,B省省长是小张,这样牵强的理解为小王是A省的一个引用,小张则是B省的一个引用。在执行swap(小王,小张)后,产生的效果只是:现在A省省长是小张,B省省长是小王了,即现在小张代表的不再是B省,而是A省了,而对于对象本身,如A省,其地理位置,人口数量等都没有变化。不能说在swap语句执行后,A省跑到地图上B省的位置去了吧?
Example2:
执行结果:
---------SWAP UNABLE----------
Int1 is 10
Int2 is 50
---------BEFORE SWAP----------
Int1 is 20
Int2 is 30
---------SWAP ENABLE----------
Int1 is 30
Int2 is 20
首先和上面例子一样,swap(obj1, obj2)也是换汤不换药的,所以交换失败。但是swapx则交换数据成功了,我们还拿上面省长的例子来解释这个现象:
国家要求小王代表的A省的C市市长和小张代表的B省的D市市长交换职位,可以吗?当然可以了,所以交换成功。
我们最后再回到Example1的问题,如果我就想交换两个int值呢?其实也不是没有办法的。
执行结果:
---------BEFORE SWAP----------
Int1 is 20
Int2 is 30
---------SWAP ENABLE----------
Int1 is 30
Int2 is 20
小记:
C++:使用分界符&标示引用
C#: 使用ref关键字标示引用
好了,关于传参的问题我的理解就是这样的。如有错误,敬请指出。
首先,我们要明确下面这两条不可争论的事实了:
【1】、对象是传引用的
【2】、基本类型是传值的
我对这个问题是这样理解的:
有过C++背景的朋友可能都会有一个认识,因为C/C++传参有很多种选择,直接传递对象或值,或者传递指针,传递引用等。而大家都有个共识,那就是在传递基本数据类型时,选择第一种,而传递对象的时候则选用传指针或者引用。这点可以从数据传输效率的角度上得到解释。
而Java创始人James在某些方面还是得借鉴一些C的思想的,所以上述两条就比较好理解了。
个人对传参的理解是:
函数参数相对其他字段,在编译器里肯定会有特殊处理的,而一般的编译器则是这样处理:
在运行栈中拷贝一份传递过来的参数(值参),而后面函数体的关于值参的操作实际上都是针对运行栈里保存的备份操作的。可以用这种理解验证一下C++的三种情况。例如传递过来的是引用,则编译器的处理流程是这样的:
首先拷贝传递来的值参(注意:值参也是引用,Java里new之后获得的都是对象的引用,而不是对象本身,这点和c++很不同),然后将其压入运行栈,后面的操作也就是对这份拷贝(也是对预期的对象的引用,所以可以到达对象)操作了。
我们看看以下的几个例子来增加对上述思想的理解。
Example1:
package com.shansun.ref; public class RefInteger { public RefInteger() { } public void swap(Integer para1, Integer para2) { Integer tmp; tmp = para1; para1 = para2; para2 = tmp; } public void print(int int1, int int2) { System.out.println("Int1 is " + int1); System.out.println("Int2 is " + int2); } public static void main(String[] args) { Integer int1 = new Integer(10); Integer int2 = new Integer(50); RefInteger ref = new RefInteger(); System.out.println("---------SWAP UNABLE----------"); ref.swap(int1, int2); ref.print(int1, int2); } }
运行结果:
---------SWAP UNABLE----------
Int1 is 10
Int2 is 50
我们都知道一点:void swap(int, int)是不能达到交换两个参数的值的。我们这里试试使用Integer对象呢?同样也交换失败,原因很简单:void swap(Integer para1, Integer para2)函数传递进来的是两个类型为Integer类的引用,而在函数体里实现的功能只是改变了para1和para2引用的对象,而para1和para2在内存中的值却一点变化都没有。可能这样理解更加形象一点:
例如,A省省长是小王,B省省长是小张,这样牵强的理解为小王是A省的一个引用,小张则是B省的一个引用。在执行swap(小王,小张)后,产生的效果只是:现在A省省长是小张,B省省长是小王了,即现在小张代表的不再是B省,而是A省了,而对于对象本身,如A省,其地理位置,人口数量等都没有变化。不能说在swap语句执行后,A省跑到地图上B省的位置去了吧?
Example2:
package com.shansun.ref; public class RefObject { int val; public RefObject(int val) { this.val = val; } public void setVal(int val) { this.val = val; } public int getVal() { return this.val; } public void print() { System.out.println("Now val is " + val); } public static void swap(RefObject obj1, RefObject obj2) { RefObject tmp; tmp = obj1; obj1 = obj2; obj2 = tmp; } public static void swapx(RefObject obj1, RefObject obj2) { int tmp; tmp = obj1.getVal(); obj1.setVal(obj2.getVal()); obj2.setVal(tmp); } public static void main(String[] args) { RefObject obj1 = new RefObject(10); RefObject obj2 = new RefObject(50); obj1.print(); obj2.print(); swap(obj1, obj2); obj1.print(); obj2.print(); swapx(obj1, obj2); obj1.print(); obj2.print(); } }
执行结果:
---------SWAP UNABLE----------
Int1 is 10
Int2 is 50
---------BEFORE SWAP----------
Int1 is 20
Int2 is 30
---------SWAP ENABLE----------
Int1 is 30
Int2 is 20
首先和上面例子一样,swap(obj1, obj2)也是换汤不换药的,所以交换失败。但是swapx则交换数据成功了,我们还拿上面省长的例子来解释这个现象:
国家要求小王代表的A省的C市市长和小张代表的B省的D市市长交换职位,可以吗?当然可以了,所以交换成功。
我们最后再回到Example1的问题,如果我就想交换两个int值呢?其实也不是没有办法的。
package com.shansun.ref; public class RefInteger { int int1, int2; public RefInteger(int int1, int int2) { this.int1 = int1; this.int2 = int2; } public void swap() { int tmp; tmp = int1; int1 = int2; int2 = tmp; } public void print() { System.out.println("Int1 is " + int1); System.out.println("Int2 is " + int2); } public static void main(String[] args) { RefInteger ref = new RefInteger(20, 30); System.out.println("---------BEFORE SWAP----------"); ref.print(); System.out.println("---------SWAP ENABLE----------"); ref.swap(); ref.print(); } }
执行结果:
---------BEFORE SWAP----------
Int1 is 20
Int2 is 30
---------SWAP ENABLE----------
Int1 is 30
Int2 is 20
小记:
C++:使用分界符&标示引用
C#: 使用ref关键字标示引用
好了,关于传参的问题我的理解就是这样的。如有错误,敬请指出。
发表评论
-
Interesting interview question…
2011-06-23 19:10 1388Today I was asked this questi ... -
简单易用的Web框架:SummerCool介绍
2011-05-10 19:01 4699SummerCool是国内某大型电子商务平台的架构师自 ... -
[转]Eclipse插件:Java AST View
2011-05-06 16:03 4587转载:http://www.blogjava.net/life ... -
Eclipse之Debug技巧
2011-05-02 15:30 1525你认为你的eclipse debug技能都学会了吗?能够熟 ... -
AccessController.doPrivileged 小记
2011-04-29 20:29 2033原文:http://blog.csdn.net/tea ... -
推荐一个下载源码的网站
2011-04-29 20:26 1208http://olex.openlogic.com/ 这个网 ... -
Java解析xml禁止校验dtd
2011-04-27 21:34 8274今天在做log4j.xml解析的时候,指定了如下的dtd声明: ... -
区分getName、getCanonicalName与getSimpleName
2011-04-27 18:34 5738举例,现有一个类如下: package com.sha ... -
Log4J日志解析
2011-04-25 16:12 6986在有些场景下,需要解析Log4J的日志,以为己用。比如,根据 ... -
分享个不错的网站:看JSON字符串的利器
2011-04-20 20:09 1271分享个不错的网站:看JSON字符串的利器or胸器 http: ... -
Regex:密码验证
2011-04-13 18:45 19514.当且仅当含数字和字母的密码验证 如果密码当且仅当 ... -
JDBC操作数据库时切记关闭资源
2011-04-08 18:14 1813Error: No ManagedConnectio ... -
JDBC:如何将resultset的信息自动封装到pojo里面
2011-04-08 10:32 4271不多说了 直接上代码 Java代码 p ... -
Maven自动升级版本号并打包上传的脚本
2011-04-02 09:52 7441同事写的自动升级版本并打包上传的脚本: echo of ... -
在ibatis中使用$value$引入变量会引入SQLInjection漏洞
2011-04-01 16:26 2279(1)sql语法中的_关键字_.如果sql语句中出现存在用户输 ... -
EqualsBuilder和HashCodeBuilder
2011-03-31 19:30 2181自动化hashCode()和equals() 问题产生:当需 ... -
Eclipse中的Stack Trace Console的使用
2011-03-15 14:47 2981很多的Java程序员(特别是开发Web程序的时候),通常在 ... -
System.out.format的使用
2011-01-21 12:34 4734JDK5.0允许象C语言那样直接用printf()方法来格式化 ... -
jhat的简单使用
2011-01-18 19:41 2858leak一般会发生在容器类保存对象引用而不删除的时候,替代方法 ... -
关于变更eclipse中maven插件的repository路径
2011-01-10 10:02 16601.打开eclipse 2.window-->ref ...
相关推荐
java旺旺老师_按值传参与与按引用传参
参数是按值而不是按引用传递的说明 Java 应用程序有且仅有的一种参数传递机制,即按值传递。写它是为了揭穿普遍存在的一种神话,即认为 Java 应用程序按引用传递参数,以避免因依赖“按引用传递”这一行为而导致的...
可传入引用参数类型为:句柄,string, int
NULL 博文链接:https://m635674608.iteye.com/blog/1513061
引用类型不像值类型传值那样直接,那么引用类型是怎么样传值的呢?答案就在此文档中。
主要介绍了java通过实例了解值传递和引用传递,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
java的参数传递对比,体现了值传递和引用传递的区别,是我在java入门是写的学习demo
主要是对Java方法传值和传引用问题进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助
在传统的观念里,都认为JavaScript函数传递的是引用传递(也称之为指针传递),也有人认为是值传递和引用传递都具备。那么JS的参数传递到底是怎么回事呢?事实上以下的演示也完全可以用于Java 首先来一个比较简单的,...
下面小编就为大家带来一篇在java中实现C#语法里的按引用传递参数的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
多数面向对象语言都采用这一模式,包括Ruby、Smalltalk和Java(Java的引用类型是这样,基本类型按值传递) 共享传参是指函数的各个形式参数获得实参中各个引用的副本;也就是说,函数内部的形参是实参的别名(alias...
2、EarthPlanetApplet 程序代码如下 (1)回顾 Java 中的数组 数组也是一个对象,并且数组也是作为方法的对象引用值来传递的。 Image allImagesArray[]= new Image[NUMBER_IMAGES]; 但在创建数组的时候不使用小括号...
主要给大家介绍了关于java和jsp之间的request传值方法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
day03回顾 函数 def fn(): pass fn # 根据fn变量返回函数的引用关系 fn() # 返回调用函数后的引用关系 v1 = fn # v1 绑定 fn绑定的函数 ... 定义在函数内部的变量称为局部变量(函数的形参也是局部变量) 局部变
B) 在Java中布尔类型不能和数字之间不能来回转换,即false和true不对应任何零或非零的值。 C) 双精度类型double比单精度类型float具有更高的精度和更大的表示范围,但float类型具有速度快、占用内存小的优点。 D) 在...
kettle中使用功能java和JavaScript调用jar中的方法示例
Java_Algorithm(Java算法集合) 学习算法是为了什么? 1、应对大型IT公司的算法面试题; 2、IDE即对编译算法的封装; 3、搜索引擎中对几千、几亿数据进行优劣排序; 4、游戏对算法的引用是非常丰富的; 5、算法对...
4、命令行传参 5、可变参数 6、递归 数组 数组概述 数组声明创建 Java内存分析 三种初始化 数组的四个基本特点 数组边界 数组使用 多维数组 Arrays类 冒泡排序 稀疏数组 面向对象编程 初识面向对象 面向过程 &面向...
用类名定义一个变量的时候,定义的应该只是一个引用,外面可以通过这个引用来访问这个类里面的属性和方法,那们类里面是够也应该有一个引用来访问自己的属性和方法纳?呵呵,JAVA提供了一个很好的东西,是 this 对象...