Summary: Java中函数参数的传递
函数调用参数传递类型(java)的用法介绍.
java方法中传值和传引用的问题是个基本问题,但是也有很多人一时弄不清。
(一)基本数据类型:传值,方法不会改变实参的值。
public class TestFun {
public static void testInt(int i){
i=5;
}
public static void main(String[] args) {
int a=0
TestFun.testInt(a);
System.out.println("a="+a);
}
}
程序执行结果:a=0 。
(二)对象类型参数:传引用,方法体内改变形参引用,不会改变实参的
引用,但有可能改变实参对象的属性值。
举两个例子:
(1)方法体内改变形参引用,但不会改变实参引用,实参值不变。
public class TestFun2 {
public static void testStr(String str){
str="hello";//型参指向字符串 “hello”
}
public static void main(String[] args) {
String s="1"
TestFun2.testStr(s);
System.out.println("s="+s); //实参s引用没变,值也不变
}
}
执行结果打印:s=1
(2)方法体内,通过引用改变了实际参数对象的内容,注意是“内容”,引用还是不变的。
import java.util.HashMap;
import java.util.Map;
public class TestFun3 {
public static void testMap(Map map){
map.put("key2","value2");//通过引用,改变了实参的内容
}
public static void main(String[] args) {
Map map = new HashMap();
map.put("key1", "value1");
new TestFun3().testMap(map);
System.out.println("map size:"+map.size()); //map内容变化了
}
}
执行结果,打印:map size:2 。可见在方法testMap()内改变了实参的内容。
(3)第二个例子是拿map举例的,还有经常涉及的是StringBuffer :
public class TestFun4 {
public static void testStringBuffer(StringBuffer sb){
sb.append("java");//改变了实参的内容
}
public static void main(String[] args) {
StringBuffer sb= new StringBuffer("my ");
new TestFun4().testStringBuffer(sb);
System.out.println("sb="+sb.toString());//内容变化了
}
}
执行结果,打印:sb=my java 。
所以比较参数是String和StringBuffer 的两个例子就会理解什么是“改变实参对象内容”了。
总结:
第一:java方法基本数据类型是传值,对象类型传引用,这是千真万确的。
第二:当参数是对象时,无论方法体内进行了何种操作,都不会改变实参 对 对象的引用。
第三:当参数是对象时,只有在方法内部改变了对象的内容时,才会改变实参对象内容。
进一步的思考
可以看出Java中参数的传递是传递的值,不过这个值有两种,一种是我们看得到的值,也就是primitive类型,比如int,double,char类型的值。另一种就是我们看不到的值,也就是地址值,也可以说是引用值,就是你传递对象或数组类型的参数时传递的值。
其实我们也可以这么理解,当传参数的时候,会把参数的primitive值或者引用值copy给形式参数。因此,任你在方法里面怎么修改这些值都不会对原来的变量有影响。
但是对于引用值,如果你在方法里面利用这个引用值访问对象或者数组里面的数据或方法的时候,这和在方法外面直接做事一样的。因为他们持有的是同一个地址。
理解了这些,试想一下,如果在参数前加上final有什么好处吗?
如果是primitive的参数,有什么用?只能是说你在方法里面不能修改这个变量的值。其实你就算修改了,也只是对方法自己有影响,不会对调用者有影响。
如果是引用类型的参数呢?又有什么用?不可能说不让你修改对象的值,只能不让你修改这个形式参数变量的引用值。到底有什么好处呢?
从设计API的角度来说,如果你在primitive参数上加上final,就是告诉自己,这些值对于我的方法来说就是常量,是我需要参考的东西。他们的值在我的整个方法的所有的地方都是一样的。试想,如果不加final,有可能你在方法里面前后两次访问这个变量的值不同,因为你在这之间无意中修改了它。这样就达不到你的意图。
那么如果是引用类型的参数呢?这里面的意图,就是告诉你在方法里面访问(不论是读还是修改)的这个对象就是传进来的对象,而不是别的。同样保证你在方法里面不同地方的操作都是对这一个对象的操作。
再进一步的思考
有了前面的思考,我们就可以知道,在设计方法的时候,尽量在参数前面加上final,不管是primitive类型的还是在引用类型的前面。因为这样意图非常简单清楚,在方法里面也可以大胆的引用。回顾你需要修改它们的时候,是不是无意中把他们当成自己定义的临时变量了,这样很危险,容易出乱子。这样是为什么当你用sun的规范做check style的时候他让你改的原因。
还要再来一点思考
为什么当你调用回调函数的时候必须得加final呢?看了一篇文章说是多线程以及垃圾回收的原因迫使的,我得研究以后再来补充。
Summary: Java中函数参数的传递的更多相关文章
- 2013年6月19日星期三java中函数地址值传递
今天代码审核时确认了一个问题,理解了java中string和stringbuffer赋值问题,看到一个帖子很好,摘录如下: 理解这两个例子需要分清实参和形参的区别,引用和对象的区别 第一个例子的内部执 ...
- java中函数是值传递还是引用传递?
相信有些同学跟我一样,曾经对这个问题很疑惑.在网上也看了一些别人说的观点,评论不一.有说有值传递和引用传递两种,也有说只有值传递的,这里只说下个人见解 先看一个例子 public class Test ...
- C语言函数参数的传递详解
一.三道考题 开讲之前,我先请你做三道题目.(嘿嘿,得先把你的头脑搞昏才行--唉呀,谁扔我鸡蛋?)考题一,程序代码如下:void Exchg1(int x, int y){ int tmp; ...
- python 函数参数的传递(参数带星号的说明) 元组传递 字典传递
python中函数参数的传递是通过赋值来传递的.函数参数的使用又有俩个方面值得注意:1.函数参数是如何定义的 2.在调用函数的过程中参数是如何被解析 先看第一个问题,在python中函数参数的定义主要 ...
- python中函数参数的引用方式
值传递和引用传递时C++中的概念,在python中函数参数的传递是变量指向的对象的物理内存地址!!! python不允许程序员选择采用传值还是传引用.Python参数传递采用的肯定是“传对象引用”的方 ...
- python 函数参数的传递(参数带星号的说明)
python中函数参数的传递是通过赋值来传递的.函数参数的使用又有俩个方面值得注意:1.函数参数是如何定义的 2.在调用函数的过程中参数是如何被解析 先看第一个问题,在python中函数参数的定义主要 ...
- python函数参数的传递、带星号参数的传递
python中函数参数的传递是通过赋值来传递的.函数参数的使用又有俩个方面值得注意:1.函数参数是如何定义的 2.在调用函数的过程中参数是如何被解析 先看第一个问题,在python中函数参数的定义主要 ...
- java 中函数的参数传递详细介绍
java中函数的参数传递 总结: 1.将对象(对象的引用)作为参数传递时传递的是引用(相当于指针).也就是说函数内对参数所做的修改会影响原来的对象. 2.当将基本类型或基本类型的包装集作为参数传递时 ...
- Java中到底是值传递还是引用传递?
Java中到底是值传递还是引用传递? 我们先回顾一下基本概念 实参和形参 参数在编程语言中是执行程序需要的数据,这个数据一般保存在变量中.在Java中定义一个方法时,可以定义一些参数, 举个例子: p ...
随机推荐
- OGG 3节点级联时 关键参数
目标架构为: node1-> node2->node3 node1-> node2 已经同步中,只是需要在此基础上做个node2 ->node3 的同步. 部署后发现 node ...
- java(9)并发编程
整理自<java 并发编程的艺术> 1. 上下文切换 即使是单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制.时间片是CPU分配给各个线程的时间,因为时间 ...
- Android MediaScanner
一.MediaScanner 的使用 1)Intent.ACTION_MEDIA_SCANNER_SCAN_FILE:扫描指定文件 public void scanFileAsync(Context ...
- Setting up Unicorn with Nginx
gem install unicorn or gem 'unciron' 1 install Nginx yum install ... 2 Configuration vi /etc/nginx/n ...
- 【BZOJ3413】匹配 离线+后缀树+树状数组
[BZOJ3413]匹配 Description Input 第一行包含一个整数n(≤100000). 第二行是长度为n的由0到9组成的字符串. 第三行是一个整数m. 接下来m≤5·10行,第i行是一 ...
- Css控制网页变灰
兼容IE chrome Firefox..... html{ filter:grayscale(%); -moz-filter:grayscale(%); -o-filter:grayscale(%) ...
- redis进程守护脚本
#!/bin/bash redis_dir="/usr/local/redis" redis_conf="/usr/local/redis/redis.conf" ...
- [EF]vs15+ef6+mysql code first方式
写在前面 前面有篇文章,尝试了db first方式,但不知道是什么原因一直没有成功,到最后也没解决,今天就尝试下code first的方式. [EF]vs15+ef6+mysql这个问题,你遇到过么? ...
- Asp.net MVC]Asp.net MVC5系列——实现编辑、删除与明细信息视图
目录 概述 实现信息的明细视图 实现信息的编辑视图 实现信息的删除视图 总结 系列文章 [Asp.net MVC]Asp.net MVC5系列——第一个项目 [Asp.net MVC]Asp.net ...
- 字符串-回文-Manacher算法
http://blog.csdn.net/zzkksunboy/article/details/72600679 https://segmentfault.com/a/1190000008484167 ...