- 浏览: 1076301 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (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 1448Today I was asked this questi ... -
简单易用的Web框架:SummerCool介绍
2011-05-10 19:01 4743SummerCool是国内某大型电子商务平台的架构师自 ... -
[转]Eclipse插件:Java AST View
2011-05-06 16:03 4614转载:http://www.blogjava.net/life ... -
Eclipse之Debug技巧
2011-05-02 15:30 1559你认为你的eclipse debug技能都学会了吗?能够熟 ... -
AccessController.doPrivileged 小记
2011-04-29 20:29 2075原文:http://blog.csdn.net/tea ... -
推荐一个下载源码的网站
2011-04-29 20:26 1245http://olex.openlogic.com/ 这个网 ... -
Java解析xml禁止校验dtd
2011-04-27 21:34 8389今天在做log4j.xml解析的时候,指定了如下的dtd声明: ... -
区分getName、getCanonicalName与getSimpleName
2011-04-27 18:34 5764举例,现有一个类如下: package com.sha ... -
Log4J日志解析
2011-04-25 16:12 7053在有些场景下,需要解析Log4J的日志,以为己用。比如,根据 ... -
分享个不错的网站:看JSON字符串的利器
2011-04-20 20:09 1304分享个不错的网站:看JSON字符串的利器or胸器 http: ... -
Regex:密码验证
2011-04-13 18:45 20034.当且仅当含数字和字母的密码验证 如果密码当且仅当 ... -
JDBC操作数据库时切记关闭资源
2011-04-08 18:14 1864Error: No ManagedConnectio ... -
JDBC:如何将resultset的信息自动封装到pojo里面
2011-04-08 10:32 4307不多说了 直接上代码 Java代码 p ... -
Maven自动升级版本号并打包上传的脚本
2011-04-02 09:52 7516同事写的自动升级版本并打包上传的脚本: echo of ... -
在ibatis中使用$value$引入变量会引入SQLInjection漏洞
2011-04-01 16:26 2311(1)sql语法中的_关键字_.如果sql语句中出现存在用户输 ... -
EqualsBuilder和HashCodeBuilder
2011-03-31 19:30 2220自动化hashCode()和equals() 问题产生:当需 ... -
Eclipse中的Stack Trace Console的使用
2011-03-15 14:47 3023很多的Java程序员(特别是开发Web程序的时候),通常在 ... -
System.out.format的使用
2011-01-21 12:34 4794JDK5.0允许象C语言那样直接用printf()方法来格式化 ... -
jhat的简单使用
2011-01-18 19:41 2890leak一般会发生在容器类保存对象引用而不删除的时候,替代方法 ... -
关于变更eclipse中maven插件的repository路径
2011-01-10 10:02 17021.打开eclipse 2.window-->ref ...
相关推荐
本文将深入探讨Java中的方法调用、值传递与引用传递,并通过字节码分析来进一步理解这些概念。 首先,我们来看方法调用。在Java中,方法是一组完成特定任务的代码块,可以通过方法名来调用执行。方法调用的基本语法...
2. Java 仅支持按值传递参数,无论是基本类型还是引用类型。 3. 按值传递意味着方法内部的任何修改都不会影响到原始参数的值,除非是修改引用所指向的对象的状态。 4. 对于基本类型,传递的是原始值的拷贝,而对引用...
可传入引用参数类型为:句柄,string, int
在编程领域,我们经常需要处理各种数据类型,其中包括值类型(value types)和引用类型(reference types)。值类型如整型、浮点型、布尔型等,它们在赋值或作为参数传递时会进行副本复制,而引用类型则有所不同。本...
在Java编程语言中,参数传递主要有两种方式:值传递和引用传递。然而,Java只支持值传递,这里的“值”可以是基本类型(如int)的直接值,或者是对象的引用(即对象在内存中的地址)。当我们谈论Integer类型的参数...
"Java开启新线程并传参方法代码实现" Java开启新线程并传参方法...本文详细介绍了Java开启新线程并传参方法代码实现的两种方式:继承Thread类和实现Runnable接口。希望对大家的学习有所帮助,也希望大家多多支持我们。
java通过实例了解值传递和引用传递 Java语言中有两种基本的参数传递方式:值传递和引用传递。值传递是指在方法调用时,传递的参数是按值的拷贝传递。引用传递是指在方法调用时,传递的参数是按引用进行传递,其实...
在Python中,由于变量实际上是对象的引用,而不是对象本身,因此即使是"引用传递",也与C++或Java等语言中的引用传递有所区别。 以下是一个关于Python引用传递的例子: ```python def change_list(list): list....
总之,Java中的数组创建涉及声明和分配内存,而数组参数传递是通过值传递进行的,即传递数组的引用。了解这些基础知识对于编写高效、可维护的Java程序至关重要。希望本文提供的信息对你的学习有所帮助,如有任何疑问...
Java 有两类参数传递方式:按值传递(by value)和按引用传递(by reference),虽然 Java 没有真正的按引用传递,但其效果类似于 C++ 或 C# 中的引用传递。 1. **按值传递(by value)**: - 适用于基本数据类型...
java的参数传递对比,体现了值传递和引用传递的区别,是我在java入门是写的学习demo
### Java远程方法调用(RMI):深入解析与实践 #### 一、RMI概念与原理 Java远程方法调用(Remote Method Invocation,简称RMI)是Java平台提供的一种分布式计算模型,允许一个Java虚拟机(JVM)上的对象通过网络...
在`stringBufferUpd`方法中,`bb`对象被传递给方法后,方法内部通过引用修改了`StringBuffer`对象的内容,所以`bb`的值在`main`方法中也发生了变化,输出为"javac"和"javac"。 这种传引用的行为有时会引发混淆,...
在Android应用开发中,Intent是连接应用程序组件的重要桥梁,它用于启动新的Activity或者Service,同时也可以在组件间传递数据。本篇文章将详细讲解如何通过Intent实现Activity之间的参数传递。 一、Intent的基本...
这里的`<%= someValueFromBackend %>`和`<%= anotherValue %>`是JSP表达式,它们会在服务器端被Java代码替换为实际值。 3. **传递参数**: JSP表达式`<%= ... %>`允许我们在JavaScript中注入Java变量的值。这些...
Java中的隐式传参详解 通过字节码看Java中的this隐式传参是Java语言中一...通过字节码分析可以看到,Java类文件中的每个方法都对应着一个Methodref项,方法调用过程也可以分为方法查找、方法解析和方法调用三个步骤。
JNA还支持自定义结构体类型映射,如`ByReference`和`ByValue`,它们分别用于传递结构体的引用和值。对于指针,JNA提供了一个`Pointer`类,它可以指向任何类型的数据,包括结构体。例如,如果你有一个接收结构体指针...
`Bin`目录则存放编译后的程序集,包括项目引用的库和自定义组件。 通过整合这些元素,我们可以构建一个Web应用程序,该应用程序能够通过POST方式调用WebService,传递参数,并解析返回的XML数据,以便在页面上展示...
在事件处理函数中,我们可以获取需要回传的值,并通过`window.opener`属性与A页面进行通信,因为`window.opener`引用了创建当前窗口的窗口对象。例如: ```javascript window.addEventListener('beforeunload', ...