函数传参的问题:
Java对对象和基本的数据类型的处理是不一样的。
和C语言一样,当把Java的基本数据类型(如int,char,double等)作为入口参数传给函数体的时候,传入的参数在函数体内部变成了局部变量,这个局部变量是输入参数的一个拷贝,所有的函数体内部的操作都是针对这个拷贝的操作,函数执行结束后,这个局部变量也就完成了它的使命,它影响不到作为输入参数的变量。(这种方式的参数传递往往被称为"值传递"。)
而在Java中用对象的作为入口参数的传递则缺省为"引用传递",也就是说仅仅传递了对象的一个"引用",这个"引用"的概念同C语言中的指针引用是一样的。当函数体内部对输入变量改变时,实质上就是在对这个对象的直接操作。 这一点上,String以及简单类型封装类(如Integer、Double等)有所不同,他们作为参数被传入函数的时候,是“值传递”,这里举个例子,程序:
public class StringTest ...{
static void strChange(String s)...{
s = "str changed";
}
public static void main(String[] args) ...{
String str = "init str";
StringTest.strChange(str);
System.out.println(str); }
}
程序输出结果是:init str 。事实上,虽然是String对象作为参数传进了函数,但是函数里对他的改变,其实是新建一个String的过程,而不是改变值(String是immutable的, 不可改变)
除了在函数传值的时候是"引用传递",在任何用"="向对象变量赋值的时候都是"引用传递"。
另外,在util包中的集合类,存储的也只是对象的引用。
关于clone
Java的所有类都默认继承java.lang.Object类,在java.lang.Object类中有一个方法clone()。JDK API的说明文档解释这个方法将返回Object对象的一个拷贝。要说明的有两点:一是拷贝对象返回的是一个新对象,而不是一个引用。二是拷贝对象与用new操作符返回的新对象的区别就是这个拷贝已经包含了一些原来对象的信息,而不是对象的初始信息。
举个简单的clone的例子:
@Override
protected Object clone() throws CloneNotSupportedException ...{
CloneTest o = null;
try...{
o = (CloneTest)super.clone();
}catch(CloneNotSupportedException e)...{
e.printStackTrace();
}
return o;
}
其中需要注意的是,实现Cloneable接口:Cloneable接口是不包含任何方法的。这个接口仅仅是一个标志,而且这个标志也仅仅是针对Object类中clone()方法的,如果clone类没有实现Cloneable接口,并调用了Object的clone()方法(也就是调用了super.Clone()方法),那么Object的clone()方法就会抛出CloneNotSupportedException异常。
同时,Object类的clone()是一个native方法,native方法的效率一般来说都是远高于java中的非native方法。这也解释了为什么要用Object中clone()方法而不是先new一个类,然后把原始对象中的信息赋到新对象中,虽然这也实现了clone功能。
另外,为了让其它类能调用这个clone类的clone()方法,重载之后可以把clone()方法的属性设置为public。
关于shadow copy 和deep copy
调用Object类中clone()方法产生的效果是:先在内存中开辟一块和原始对象一样的空间,然后原样拷贝原始对象中的内容。对基本数据类型,这样的操作是没有问题的,但对非基本类型变量,我们知道它们保存的仅仅是对象的引用,这也导致clone后的非基本类型变量和原始对象中相应的变量指向的是同一个对象。
这就是shadow和deep copy的根本所在。
要实现deep copy,最简单的方法莫过于在clone时,对类里面的对象域(即属性域类型是对象)也进行clone操作。(层次多的可能需要多层的deep copy)
有关deep copy,还有一点需要说明的是刚才提到过的String以及Integer、Double等类型。这些类型出现在class里的时候,虽然他们是Object,但是,对该class的拷贝会自动完成对这些域的deep copy. 理由跟前面说的差不多。很多书上说可以把这几个类看成基本类型,也就是这个道理。
参考:
http://www-128.ibm.com/developerworks/cn/java/l-jpointer/index.html
分享到:
相关推荐
本文将深入探讨Java中的引用以及对象的克隆机制,包括浅拷贝和深拷贝的区别及其应用场景。 #### 二、Java中的引用 在Java中,当使用`new`关键字创建一个对象时,实际上创建的是一个指向该对象的引用。例如,以下...
### Java中的`clone`方法详解:浅拷贝与深拷贝 #### 一、引言 在Java中,`clone`方法提供了一种快速复制对象的方式。它属于`Object`类的一部分,但需要显式地在子类中声明并实现`Cloneable`接口才能正常使用。本文...
本文将深入探讨Java中的`clone`方法,包括其工作原理、使用场景、注意事项以及一些个人实践心得。 首先,让我们理解什么是`clone`。在Java中,`clone`方法主要用于创建一个现有对象的副本,这个副本与原始对象具有...
在Java编程语言中,`Cloneable`接口和`clone()`方法是两个重要的概念,它们用于对象复制。在本文中,我们将深入探讨Java中的浅克隆(shallow clone)和深克隆(deep clone),并结合测试代码进行分析。 首先,让...
让我们深入探讨`clone()`方法以及它在实际编程中的应用。 首先,`clone()`方法是Java Object类的一个成员方法,这意味着所有Java类都隐式地继承了这个方法。它的主要作用是创建并返回当前对象的一个副本,也就是浅...
Java中的`clone`方法是Java语言提供的一种复制对象的方式,它允许创建一个对象的副本,这个副本与原对象具有相同的属性值,但它们是两个独立的对象,修改副本不会影响原对象。`clone`方法存在于Java的`java.lang....
在Java编程语言中,克隆(Clone)机制是一种创建对象副本的方法,它允许开发者创建一个已有对象的新实例,这个新实例与原对象具有相同的属性值,但却是两个独立的对象,彼此的操作不会互相影响。克隆机制在某些情况...
Java中的clone方法详解 在Java语言中,clone方法是一个非常重要的概念,它允许对象被复制,从而创造出一个新的对象。下面我们将详细介绍Java中的clone方法,并讨论它的实现机制和应用场景。 什么是clone方法 ...
本资料"Java中clone方法共6页.pdf.zip"可能包含了关于如何理解和使用`clone()`方法的详细解释,以及它在实际开发中的应用示例。 `clone()`方法的主要用途是创建一个现有对象的副本,这个副本与原始对象具有相同的...
在Java中,任何类都可以被克隆,但默认的`Object`类的`clone()`方法仅提供浅复制,即如果对象中包含其他对象的引用,这些引用的对象不会被复制,而是共享。因此,如果我们想要实现深复制,需要自定义`clone()`方法,...
下面我们将详细探讨Java中的克隆以及提供的实例代码。 首先,让我们了解`Cloneable`接口。在Java中,如果一个类想要实现`clone()`方法,必须实现`Cloneable`接口。如果不这样做,Java会抛出`...
Java 中 clone() 的使用方法 Java 中的 clone() 方法是对象的复制方法,其主要作用是创建一个与原对象相同的新对象。下面将详细介绍 Java 中 clone() 方法的使用方法。 什么是 clone() 方法? clone() 方法是 ...
通过上述分析,我们可以清楚地了解到Java中引用和函数参数传递的基本概念以及它们的具体应用。了解这些概念对于正确使用Java进行编程非常重要,尤其是在处理复杂的数据结构和对象交互时。希望本文能帮助读者更好地...
在标签"java clone()"中,我们可以推断这篇博客可能还讨论了关于Java中对象复制的各种策略,如序列化和反序列化,以及`CopyConstructor`,这些都是创建对象副本的替代方法,特别是当`clone()`不能满足特定需求时。...
Java中的对象创建主要有两种方式,即使用`new`操作符创建新对象以及通过`clone`方法复制已有对象。本文将从JVM的角度深入探讨Java的`clone`操作,揭示其工作原理及其潜在的问题。 首先,让我们理解`clone`方法的...
在Java编程语言中,`clone`是一个非常重要的概念,它涉及到对象复制和对象的深拷贝与浅拷贝。本文将深入探讨Java中的`clone`方法及其相关知识点。 首先,`clone`方法是Java `Object`类的一个成员方法,定义为`...
Java中的`clone()`方法是Object类的一个成员方法,它提供了创建一个对象副本的功能。这篇文章将深入探讨`clone()`方法的工作原理、使用场景以及浅拷贝(shallow clone)与深拷贝(deep clone)的区别。 首先,让...
不过,`clone`方法有时可能会带来一些复杂性,例如需要处理`CloneNotSupportedException`,以及处理深拷贝的情况。在某些情况下,使用构造函数或者序列化/反序列化等其他技术来创建对象的副本可能是更好的选择。