函数调用参数传递类型(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中函数参数的传递的更多相关文章

  1. 2013年6月19日星期三java中函数地址值传递

    今天代码审核时确认了一个问题,理解了java中string和stringbuffer赋值问题,看到一个帖子很好,摘录如下: 理解这两个例子需要分清实参和形参的区别,引用和对象的区别 第一个例子的内部执 ...

  2. java中函数是值传递还是引用传递?

    相信有些同学跟我一样,曾经对这个问题很疑惑.在网上也看了一些别人说的观点,评论不一.有说有值传递和引用传递两种,也有说只有值传递的,这里只说下个人见解 先看一个例子 public class Test ...

  3. C语言函数参数的传递详解

    一.三道考题 开讲之前,我先请你做三道题目.(嘿嘿,得先把你的头脑搞昏才行--唉呀,谁扔我鸡蛋?)考题一,程序代码如下:void Exchg1(int x, int y){   int tmp;    ...

  4. python 函数参数的传递(参数带星号的说明) 元组传递 字典传递

    python中函数参数的传递是通过赋值来传递的.函数参数的使用又有俩个方面值得注意:1.函数参数是如何定义的 2.在调用函数的过程中参数是如何被解析 先看第一个问题,在python中函数参数的定义主要 ...

  5. python中函数参数的引用方式

    值传递和引用传递时C++中的概念,在python中函数参数的传递是变量指向的对象的物理内存地址!!! python不允许程序员选择采用传值还是传引用.Python参数传递采用的肯定是“传对象引用”的方 ...

  6. python 函数参数的传递(参数带星号的说明)

    python中函数参数的传递是通过赋值来传递的.函数参数的使用又有俩个方面值得注意:1.函数参数是如何定义的 2.在调用函数的过程中参数是如何被解析 先看第一个问题,在python中函数参数的定义主要 ...

  7. python函数参数的传递、带星号参数的传递

    python中函数参数的传递是通过赋值来传递的.函数参数的使用又有俩个方面值得注意:1.函数参数是如何定义的 2.在调用函数的过程中参数是如何被解析 先看第一个问题,在python中函数参数的定义主要 ...

  8. java 中函数的参数传递详细介绍

    java中函数的参数传递 总结: 1.将对象(对象的引用)作为参数传递时传递的是引用(相当于指针).也就是说函数内对参数所做的修改会影响原来的对象.  2.当将基本类型或基本类型的包装集作为参数传递时 ...

  9. Java中到底是值传递还是引用传递?

    Java中到底是值传递还是引用传递? 我们先回顾一下基本概念 实参和形参 参数在编程语言中是执行程序需要的数据,这个数据一般保存在变量中.在Java中定义一个方法时,可以定义一些参数, 举个例子: p ...

随机推荐

  1. JavaScript怎样学

    嘿,我最近接到一个 Web 项目,不过老实说,我这两年没怎么接触 Web 编程,听说 Web 技术已经发生了一些变化.听说你是这里对新技术最了解的 Web 开发工程师? 准确地说,我是一名「前端工程师 ...

  2. C# 批量上传

    完整例子下载 效果: 前台: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="d ...

  3. 无线路由器无线AP模式的配置

    环境介绍>>>>>>>>>>>>>>>>>>>交换机类型:三层交换机无线路由器品牌:T ...

  4. android极光杀掉程序收不到通知

    http://docs.jpush.io/guideline/faq/#android 第三方系统收不到推送的消息 由于第三方 ROM 的管理软件需要用户手动操作 小米[MIUI] 自启动管理:需要把 ...

  5. node.js发送邮件email

    通常我们做node项目时,可能我们会碰到做一个简单的邮件反馈,那么我们今天就来讨论一下,其中遇到的各种坑. 总的来说做这个东西,我们可能需要node第三方依赖模块,来实现我们要达到的效果. 这里我推荐 ...

  6. Guideline 2.5.1 - Performance - Software Requirements

    Guideline - Performance - Software Requirements Your app uses the "prefs:root=" non-public ...

  7. zookeeper 安装的三种模式

    Zookeeper安装 zookeeper的安装分为三种模式:单机模式.集群模式和伪集群模式. 单机模式 首先,从Apache官网下载一个Zookeeper稳定版本,本次教程采用的是zookeeper ...

  8. Hive show

    CREATE TABLE page_view(viewTime INT, userid BIGINT,p_date timestamp, page_url STRING, referrer_url v ...

  9. Zabbix监控Nginx状态信息

    首先要检查Nginx是否安装了 http_stub_status_module 模块,通过下面的命令可以看到编译参数.yum安装的默认会带有这个模块. [root@kafka60 ~]# /data/ ...

  10. java 类中的细节

    java 中类: 类是用于描述统一类型的对象的一个抽象的概念,类中定义了这一类对象所因具有的静态和动态属性. 举例: 瓶子静态: 有一个口.长长的形状-->java类中的成员变量动态属性: 可以 ...