java中参数传递方式话题终结实例

java新手入门面临的一个经典的话题,本文意在终结这个话题,java中有说法:Java里面参数传递都是按值传递,怎么理解这句话?用文字说明恐怕不容易说明白,说明白恐怕也难以想明白。

前提

先明确一下,按值还是按引用的概念,它是来自c++语言,引用不是汉语词典中的一个词,而是c++的概念——“&”这个符号还记得吧?

为什么有这个话题呢?其一,是对按引用传递理解不透彻;其二,诸多java书籍及讨论论点并没有切中要害。��

一句话概括,按值传参还是按引用传参,既然是参数传递方式,那么只针对形参和实参,这里说的是参数本身,不是参数对象的子对象或孙子对象。

有了前提,上c++代码:

#include <iostream>

using namespace std;

class User
{
    private:
        int m_id;
    public:
        User(int id=0){m_id = id;}
        void setId(int id){m_id = id;}
        int getId(){return m_id;}
};

void test0(User t){//按值传参
  User s;
  t = s;
  t.setId(1002);
  cout << "test1:" << t.getId() << endl;
}

void test1(User *t){//按值传参
  t = new User();//指针指向了一个新对象,外面实参没变
  t->setId(1002);
  cout << "test1:" << t->getId() << endl;
}

void test2(User* & t){//按引用传参
    t = new User();//指针指向了一个新对象,外面实参也跟着变了
    t->setId(1002);
    cout << "test2:" << t->getId() << endl;
}

int main(int argc, char const *argv[]) {
  cout<< "\npass by ref:"<<endl;
  User* t = new User();
  t->setId(1001);
  cout << t->getId() << endl;
  test2(t);
  cout << t->getId() << endl;

  cout<< "\npass by value:"<<endl;
  t = new User();
  t->setId(1001);
  cout << t->getId() << endl;
  test1(t);
  cout << t->getId() << endl;
  return 0;
}

输出结果:

pass by ref:
1001
test2:1002
1002

pass by value:
1001
test1:1002
1001

c++小结:

按值传递,那么在函数内修改了形参指向一个新对象,外面的实参不受影响。

按引用传递,那么在函数内修改了形参指向一个新对象,外面的实参也变了。

旨在说明问题,代码可能有内存泄漏。

上java:

package com.pollyduan.bean;

@Data
public class User {
    private Integer id;

    public static void testObject(User t){
        t=new User();//指向了一个新对象,外面实参没变
        t.setId(1002);
        System.out.println("testObject="+t);
    }

    @Test
    public void testObject(){
        User user=new User();
        user.setId(1001);
        System.out.println("user="+user);
        testObject(user);
        System.out.println("user="+user);
    }
}

输出结果:

user=User(id=1001)
testObject=User(id=1002)
user=User(id=1001)

java小结:

跟c++的逻辑比较一下,请自行对号入座。

万事无绝对,你可能发现jdk中有引用传参的例子,如:

char[] gg={'a','b','c'};
char[] newGG=new char[gg.length];
System.arraycopy(gg,0,newGG,0,gg.length);

看下源码,它不是jdk本身的方法,是JNI,也就是说是jvm的JNI库封装的方法,知道即可。

时间: 2024-12-01 00:58:47

java中参数传递方式话题终结实例的相关文章

Java中的MessageFormat.format用法实例

  这篇文章主要介绍了Java中的MessageFormat.format用法实例,本文先是讲解了MessageFormat的语法,然后给出了多个操作实例,需要的朋友可以参考下 MessageFormat本身与语言环境无关,而与用户提供给MessageFormat的模式和用于已插入参数的子格式模式有关,以生成适用于不同语言环境的消息. MessageFormat模式(主要部分): 代码如下: FormatElement: { ArgumentIndex }:是从0开始的入参位置索引. { Arg

JAVA中的final关键字用法实例详解_java

本文实例讲述了JAVA中的final关键字用法.分享给大家供大家参考,具体如下: 根据上下文环境,java的关键字final也存在着细微的区别,但通常指的是"这是无法改变的."不想改变的理由有两种:一种是效率,另一种是设计.由于两个原因相差很远,所以关键子final可能被误用. 接下来介绍一下使用到final的三中情况:数据,方法,类 final数据 许多编程语言都有某种方法,来向编译器告知一块数据是恒定不变的.有时数据的恒定不变是很有用的,例如: 1. 一个编译时恒定不变的常量 2.

JAVA中static方法的用法实例详解_java

本文实例讲述了JAVA中static方法的用法.分享给大家供大家参考,具体如下: static表示"全局"或者"静态"的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static修饰的成员变量和成员方法独立于该类的任何对象.也就是说,它不依赖类特定的实例,被类的所有实例共享.只要这个类被加载,Java虚拟机就能根据类名在运行时数据区或者方法区内找到他们.因此,static对象可以在它的任何对象创建之前访

Java中的对象和对象引用实例浅析

  本文实例讲述了Java中的对象和对象引用.分享给大家供大家参考.具体分析如下: 在Java中,有一组名词经常一起出现,它们就是"对象和对象引用",很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起了解一下对象和对象引用之间的区别和联系. 1.何谓对象? 在Java中有一句比较流行的话,叫做"万物皆对象",这是Java语言设计之初的理念之一.要理解什么是对象,需要跟类一起结合起来理解.下面这段话引自<Jav

java中输出流OutputStream 类应用实例(转)

  OutputStream类该类是字节输出流的抽象类,定义了输出流的各种操作方法.这些方法的说明如表1所示.下面通过实例介绍如何使用OutputStream类向控制台输出字符串信息.步骤如下.(1)创建OutputStreamWriteStr类,在类中创建OutputStream类的实例对象out,并为其赋值为System类的out属性,该属性是控制台的输出流,再定义一个字节数组,该数组是将要输出到控制台的字符串信息,并通过out对象在控制台输出该字节数组的内容.关键代码如下:src\com\

java中vector与hashtable操作实例分享_java

众所周知,java中vector与hashtable是线程安全的,主要是java对两者的操作都加上了synchronized,也就是上锁了.因此 在vector与hashtable的操作是不会出现问题.但是有一种情况:就是将一个hashtable copy到另一个hashtable时,假如使用putAll方法的花,会抛出一个 java.util.ConcurrentModificationException异常.先上代码: TestSync.java 复制代码 代码如下: public clas

Java中的对象和对象引用实例浅析_java

本文实例讲述了Java中的对象和对象引用.分享给大家供大家参考.具体分析如下: 在Java中,有一组名词经常一起出现,它们就是"对象和对象引用",很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起了解一下对象和对象引用之间的区别和联系. 1.何谓对象? 在Java中有一句比较流行的话,叫做"万物皆对象",这是Java语言设计之初的理念之一.要理解什么是对象,需要跟类一起结合起来理解.下面这段话引自<Java编

Java中List与数组相互转换实例分析_java

本文实例分析了Java中List与数组相互转换的方法.分享给大家供大家参考.具体如下: 今天写代码遇到一个奇怪的问题,具体代码不贴出了,写一个简化的版本.如下: ArrayList<String> list=new ArrayList<String>(); String strings[]=(String [])list.toArray(); 这样写代码个人觉得应该没什么问题,编译也没有问题.可是具体运行的时候报异常,如下:Exception in thread "mai

Java中的MessageFormat.format用法实例_java

MessageFormat本身与语言环境无关,而与用户提供给MessageFormat的模式和用于已插入参数的子格式模式有关,以生成适用于不同语言环境的消息. MessageFormat模式(主要部分): 复制代码 代码如下: FormatElement:          { ArgumentIndex }:是从0开始的入参位置索引.          { ArgumentIndex , FormatType }          { ArgumentIndex , FormatType ,