`
xinklabi
  • 浏览: 1588015 次
  • 性别: Icon_minigender_1
  • 来自: 吉林
文章分类
社区版块
存档分类
最新评论

深入探讨java中的参数传递行为

    博客分类:
  • Java
阅读更多

在java和C++中都采用了引用这个概念,但是二者的行为并不一样。java的引用其实更象c++中的指针,而非c++中的引用,的确c++的指针给我们带来强大威力的同时,也给我们带来了危险,大多的攻击也都是利用指针让系统崩溃。在许多书上都没有见到关于java中reference行为的更详细的探讨,本文便从与c++的的区别谈起:
一.先看java中的引用:

Java代码 复制代码
  1. class Person   
  2. {   
  3.  private String name;   
  4.  public Person(String name)   
  5.  {   
  6.   this.name=name;   
  7.  }   
  8.  public String getName()   
  9.  {   
  10.   return name;   
  11.  }   
  12.  public void setName(String name)   
  13.  {   
  14.   this.name = name;   
  15.  }   
  16. }  
class Person
{
 private String name;
 public Person(String name)
 {
  this.name=name;
 }
 public String getName()
 {
  return name;
 }
 public void setName(String name)
 {
  this.name = name;
 }
}


现产生两个对象 :

Java代码 复制代码
  1. Person p1=new Person("Zhangsan");   
  2. Person p2=new Person("Lisi");  
Person p1=new Person("Zhangsan");
Person p2=new Person("Lisi");


引用Person p=p1,p1=p2;
测试结果p.getName(): Zhangsan;
p1.getName():Lisi;
P2.getName :Lisi;
而在c++的引用中其结果应该都是Lisi即p2的name(因为p1的改变会影响p);
上述结果显示:在java中referece其行为就是c++中的指针,而不是c++中的引用.
但是java的referece是一种安全的指针,不仅受到编译器的保护,还受到执行系统的保护。但java没有“指针”运算。c++中的引用感觉叫做别名更合适,许多语言都用alias关键字来定义别名。
二、java中的参数传递问题--By value or By reference
java中的参数传递都是采用by value.其实这句话是个笼统的说法,如果不加思索或许不能理解其真正的含义。
首先说什么是by value,by value是指在参数结合的时候,形参是否是实参的一个副本,如果产生这个副本那么我们说是by value,否则我们说是by reference.
java中的基本类型和c、c++语言一样采用by value传参是毋庸置疑的。
那么java有在参数传递的时候有没有by reference?回答是否定的。java中的一切类型在传递参数的时候都是传值的。
   首先,我们想想c++和java中的对象有什么区别?其实没有什么区别,只是java中的对象必须由reference来持有,而c++的对象可以单独存在。那好,那就让我们看看java是怎么传递对象的:

Java代码 复制代码
  1. public static void swap(Person person1, Person person2) // doesn't work   
  2. {   
  3.    Person temp = person1;   
  4.    person1 = person2;   
  5.    person2 = temp;   
  6. }   
  7. Person a = new Person("Alice");   
  8. Person b = new Employee("Bob");   
  9. swap(a, b);  
public static void swap(Person person1, Person person2) // doesn't work
{
   Person temp = person1;
   person1 = person2;
   person2 = temp;
}
Person a = new Person("Alice");
Person b = new Employee("Bob");
swap(a, b);


能工作么?不能。为什么?
我们看看:
当我们传递参数的时候,我们传递的是对象么?不,是对象的一个句柄(引用、“指针”)。java的对象只能
由引用来持有。如果你对c++熟悉,那么上面的过程我们翻译过来:

Java代码 复制代码
  1. static void swap(Person *person1,Person *person2)   
  2. {   
  3.   Person *temp = person1;   
  4.   person1 = person2;   
  5.   person2 = temp;   
  6. }   
  7. Person *a = new Person("Alice");   
  8. Person *b = new Person("Bob");   
  9. swap(a,b);  
static void swap(Person *person1,Person *person2)
{
  Person *temp = person1;
  person1 = person2;
  person2 = temp;
}
Person *a = new Person("Alice");
Person *b = new Person("Bob");
swap(a,b);


这两段代码产生的行为是一样的,都不能正常工作(即无法完成我们的交换工作)。

原因:C语言中实参变量和形参变量之间的数据传递是单向的“值传递”方式。用指针变量做函数参数时同样要遵循这一原则。不可能通过执行调用函数来改变实参指针变量的值,“但是可以改变实参指针变量所指变量的值”。上述代码若改成

       Person temp;//是类型

       temp = *person1;

       *person1 = *person2;//交换的是值

       *person2 = temp;

就可以了。
那我们先想想c++是怎么实现对象的交换的?你或许一口就说出使用引用和指针做参数。但是上面的参数是指针
作为参数呀!原因在于:在c++中我们传递的参数的确能是对象:

Java代码 复制代码
  1. Person a("Alice");   
  2. Person b("Bob");   
  3. swap(a,b);  
Person a("Alice");
Person b("Bob");
swap(a,b);


这样可以成功完成交换动作.
前两段的代码不能工作的原因在于:
  但我们传递实参的时候,我们传递的是指针("指针"),传递的过程,指针("指针")进行了复制,如下图示:
a--->对象1<----a'(其中a',b'分别为a,b在传递参数的时候产生的副本)
b--->对象2<----b'
进入函数体后副本发生了交换,如下图示:
a-->对象1<---b'
b-->对象2<---a'
我们可以看出a和b安然无恙的指向了原来的对象.这就是产生上述结果的原因.
但java可以在函数体内修改对象的值:

Java代码 复制代码
  1. static void changName(Person person){   
  2.  person.setName("Bob");   
  3. }   
  4. changName(a);  
static void changName(Person person){
 person.setName("Bob");
}
changName(a);


对java传递参数总结:
1)一个方法不能够修改一个基本类型的实参的值
2)一个方法可以改变对象的状态.
3)一个方法不能让实参引用指向另一个对象.

  • 大小: 51.7 KB
分享到:
评论

相关推荐

    Java参数传递PPT

    Java参数传递机制是编程中的重要概念,尤其是在Java中,它对于理解如何在方法间操作数据至关重要。本PPT深入探讨了这一主题,旨在帮助学习者彻底理解Java中的参数传递方式。 首先,我们要回顾面向对象的基本概念。...

    Java参数分析

    本文将深入探讨Java中的参数分析,结合给定的资源《参数分析总结.doc》,我们将涵盖以下几个核心知识点: 1. **基本类型与引用类型参数**: - Java中有两种类型的参数:基本类型(如int, double, boolean等)和...

    Java-Java面向对象中引用传递教程

    本教程将深入探讨Java中的引用传递机制,并通过视频教程的形式帮助学习者更好地理解和应用这一概念。 首先,理解“引用”在Java中的含义至关重要。在Java中,当我们声明一个对象变量时,实际上我们得到的是指向对象...

    java及C++中传值传递、引用传递和指针方式的理解.docx

    本文将深入探讨Java与C++这两种广泛使用的编程语言中参数传递的方式,包括值传递、引用传递以及C++中的指针传递,并通过具体的代码示例来帮助理解这些概念。 #### 值传递 值传递是最简单的参数传递方式之一,它指...

    eclipse java 命令行参数

    这篇博客文章将探讨如何在Eclipse中配置和使用Java命令行参数,这对于理解程序的运行行为以及调试是非常有帮助的。 在Java程序中,命令行参数是通过`main`方法的`String[] args`数组传递的,它们允许我们在不修改...

    深入Java核心Java中多态的实现机制.pdf

    以下是深入探讨Java中多态实现机制的详细说明: 1. **子类型多态**: - 子类型多态是Java中最常见的多态形式,它基于继承和方法的覆盖。当一个派生类对象通过基类引用调用方法时,实际执行的是派生类中重写的方法...

    java8 中文文档

    下面我们将深入探讨一些 Java 8 的核心知识点。 1. **函数式编程**: - **Lambda 表达式**:Java 8 引入了 Lambda 表达式,使得编写简洁、可读性强的代码成为可能。Lambda 可以被当作一种匿名函数,用于传递行为...

    浅谈Java中真的只有值传递么

    本文将深入探讨Java中参数传递的实质,以帮助理解和澄清这一问题。 首先,我们需要理解值传递和引用传递的基本概念。值传递是指当函数或方法接收一个参数时,实际传递的是该参数值的一个副本。这意味着在函数内部对...

    Java对象及其引用的理解

    本文将深入探讨Java中的对象、引用以及它们之间的关系,并结合值传递的概念进行解析。 首先,我们需要理解什么是Java对象。在Java中,对象是类的实例。当我们使用`new`关键字创建一个类的实例时,就创建了一个对象...

    MLDN魔乐JAVA_08字符串题目、引用传递.rar

    1. 参数传递方式:Java中的参数传递总是按值传递,但对于对象类型,实际上是传递对象的引用(地址)。这意味着,函数内部对参数对象的修改会影响到原始对象,除非是基本类型。 2. 基本类型与引用类型的区别:基本...

    Java学习资料-行为型设计模式

    这里我们将深入探讨两种行为型设计模式:责任链模式(Chain of Responsibility)和命令模式(Command Pattern)。 首先,责任链模式是一种结构型设计模式,其核心思想是将多个处理者组织成一个链条,每个处理者都有...

    JAVA语言深入--多线程

    本篇将深入探讨Java中的多线程机制,包括线程的创建、管理以及如何处理并发环境中的数据安全问题。 首先,我们需要理解什么是线程。线程是操作系统分配CPU时间的基本单位,是程序执行的流。在Java中,每个程序都有...

    经典的Java中文ppt课件

    - 方法定义、调用和参数传递,理解方法作为代码重用的手段。 - 类的定义,包括属性(字段)和行为(方法)。 - 对象的创建和初始化,以及构造器的概念。 - 类的封装、继承和多态性,这是面向对象编程的三大特性...

    值传递与引用传递-内存解析

    在编程语言中,值传递和引用传递是函数参数传递的两种基本方式,它们涉及到内存管理、数据安全以及程序效率等多个重要方面。这篇文章将深入探讨这两种传递方式,并通过内存解析来帮助理解它们的工作原理。 首先,...

    java中回调函数的简单实现

    下面我们将深入探讨回调函数的基本原理、应用场景以及如何在Java中实现回调。 首先,回调函数的主要优点是可以解耦代码,使得调用者和被调用者之间不直接依赖具体的实现。例如,在事件驱动的系统中,事件监听器就是...

    Java语言规范+Java虚拟机规范(Java8、Java9)

    本篇文章将详细探讨Java语言规范与Java虚拟机规范在Java 8和Java 9版本中的关键知识点。 首先,Java语言规范(Java Language Specification, JLS)是Java编程语言的官方文档,它详细规定了语言的各个方面,包括语法...

    Java中委托小用法,看了就会

    本文将深入探讨如何在Java中实现委托模式,并通过一个名为`DelegateDemo`的示例来阐述其用法。 ### 什么是委托? 委托是一种设计模式,它允许我们将行为(即方法调用)作为参数传递给其他对象。这种模式提高了代码...

    java接口的不同使用

    本文将深入探讨Java接口的使用方法,帮助你理解其核心特性、作用以及如何在实际编程中灵活运用。 1. **接口的定义与特点** - 接口中所有的方法默认都是抽象的(abstract)和公开的(public),不需要声明这两个...

    java中的反射reflect

    以下我们将深入探讨Java反射的基本概念、主要API以及如何通过给定的代码示例来理解反射的应用。 首先,让我们了解什么是类的反射。在Java中,`java.lang.Class` 类代表了运行时的类信息。我们可以通过一个类的全名...

Global site tag (gtag.js) - Google Analytics