【vb精品源码栏目提醒】:网学会员为需要vb精品源码的朋友们搜集整理了【精品】Java程序员面试宝典(第2版) - 招聘面试相关资料,希望对各位网友有所帮助!
第 6 章 传递与引用J ava 语言明确说明取消了指针,因为指针往往是在带来方便的同时导致代码不安全 的根源,而且还会使程序变得非常复杂和难以理解,滥用指针写成的代码不亚于使用早已臭名昭著的 GOTO 语句。
Java 放弃指针的概念绝对是极其明智的。
但这只是在Java 语言中没有明确的指针定义,实质上,每一个 new 语句返回的都是一个指针的引用, ,只不过在大多数时候 Java 不用关心如何操作这个“指针” 更不用像在操作 C的指针那样胆战心惊,唯一要多注意的是在给函数传递对象的时候。
传值与引用问题中的静态变量、私有变量、clone 等问题也是各大公司的常备考点。
本章不对传值与引用基本知识做回顾和分析(请参考其他经典著作),只是通过对各公司面试题目进行全面仔细的解析,帮读者解决其中的难点。
以下的考题来自真实的笔试资料,希望读者先不要看答案,自我解答后再与答案加以比对,找出自己的不足。
第 6 章 传递与引用 6.1 传值与传引用 面试例题 1:Explain call by value and call by reference. Which of these two does Java support(解释:Java 中是传值还是传引用)中国大陆某著名网络公司 B2009 年 9 月面试题 解析:就像光到底是波还是粒子的问题一样众说纷纭,对于 Java 参数是传值还是 传引用的问题,也有很多错误的理解和认识。
我们首先要搞清楚一点就是:不管 Java 参数的类型是什么,一律传递参数的副本。
对此,thinking in Java 一书给出的经典解释 是 When you’re passing primitives into a method you get a distinct copy of the primitive. When you’re passing a reference into a method you get a copy of the reference.(如果 Java ) 是传值,那么传递的是值的副本;如果 Java 是传引用,那么传递的是引用的副本。
在 Java 中,变量分为以下两类: ① 对于基本类型变量(int、long、double、float、byte、boolean、char),Java 是 (这里 Java 和 C相同) 传值的副本。
② 对于一切对象型变量,Java 都是传引用的副本。
其实传引用副本的实质就是复 (这里 Java 和 C不 制指向地址的指针,只不过 Java 不像 C中有显著的和amp符号。
同,在 C中,当参数是引用类型时,传递的是真实引用而不是引用副本) 需要注意的是:String 类型也是对象型变量,所以它必然是传引用副本。
不要因为 61 Java 程序员面试宝典(第 2 版)String 在 Java 里面非常易于使用,而且不需要 new,就被蒙蔽而把 String 当做基本变量类型。
只不过 String 是一个非可变类,使得其传值还是传引用显得没什么区别。
对基本类型而言,传值就是把自己复制一份传递,即使自己的副本变了,自己也不变。
而对于对象类型而言,它传的引用副本(类似于 C中的指针)指向自己的地址,而不是自己实际值的副本。
为什么要这么做呢?因为对象类型是放在堆里的,一方面,速度相对于基本类型比较慢,另一方面,对象类型本身比较大,如果采用重新复制对象值的办法,浪费内存且速度又慢。
就像你要张三(张三相当于函数)打开仓库并检查库里面的货物(仓库相当于地址),有必要新建一座仓库(并放入相同货物)给张三么 没有必要,你只需要把钥匙(引用)复制一把寄给张三就可以了,张三会拿备用钥匙(引用副本,但是有时效性,函数结束,钥匙销毁)打开仓库。
在这里提一下,很多经典书籍包括 thinking in Java 都是这样解释的:“不管是基本类型还是对象类型,都是传值。
”这种说法也不能算错,因为它们把引用副本也当做是 。
一种“值” 但是笔者认为:传值和传引用本来就是两个不同的内容,没必要把两者弄在一起,弄在一起反而更不易理解。
下面看几个例子。
例 1: public class Test 62 第 6 章 传递与引用 public static void testboolean test test test System.out.printlnquotIn testboolean : test quot test public static void mainString args boolean test true System.out.printlnquotBefore testboolean : test quot test testtest System.out.printlnquotAfter testboolean : test quot test 运行结果: Before testboolean : test true In testboolean : test false After testboolean : test true 不难看出,虽然在 testboolean 方法中改变了传进来的参数值,但对这个参数源变量本身并没有影响,即对 main String 方法中的 test 变量没有影响,说明参数类型是简单类型的时候,是按值传递的。
以参数形式传递简单类型的变量时,实际上是将参数的值作为一个副本传进方法函数的,那么在方法函数中不管怎么改变其值,其结果都是只改变了副本的值,而不是源值。
例 2: public class Test public static void testStringBuffer str str.appendquot Worldquot public static void mainString args StringBuffer string new StringBufferquotHelloquot teststring System.out.printlnstring 63 Java 程序员面试宝典(第 2 版) 运行结果如下: Hello World teststring调用了 testStringBuffer方法,并将 string 作为参数传递了进去。
这里 string是一个引用,Java 对于引用形式传递对象类型的变量时,实际上是将引用作为一个副本传进方法函数的。
那么这个函数里面的引用副本所指向的是什么呢?是对象的地址。
通过引用副本(复制的钥匙)找到地址(仓库)并修改地址中的值,也就修改了对象。
例 3: public class Test public static void testString str str quotWorldquot public static void mainString args String string quotHelloquot teststring System.out.printlnstring 运行结果如下: Hello 为什么会这样呢?这是因为当执行 str quotWorldquot时,其过程为:首先系统会自动生成一个新 String 对象,并把这个新对象的值设为quotWorldquot, ( 然后把这个对象的引用赋给 str 可以理解为 str 这把钥匙原来是指向quotHelloquot这个仓库,但是现在要求 str 这把钥匙重新指向 。
我们必须清楚的一点是 String 类是 final 类型的,因此,你不可以继承quotWorldquot这个仓库)64 第 6 章 传递与引用和修改这个类。
str quotWorldquot其实是隐含的让 Java 生成一个新的 String 对象。
既然对象都是新的,那就与原来的quotHelloquot没有任何关系。
当函数结束,str 作用消失,原来的内存地址上的内容未加改变,所以打印结果仍然是 Hello。
而例 2 中的 str.appendquot Worldquot就不同了,StringBuffer 是产生一块内存空间,进行相关的增、删、改操作都在其中进行,所以为其添加一句quotWorldquot仍然是在同一段内存地址上进行,str 所指向的引用并没有改变。
答案:对于基本类型变量,Java 是传值的副本;对于一切对象型变量,Java 都是传引用的副本。
面试例题 2:下列代码的输出结果是多少,为什么?美国著名软件公司 I2009 年 11 月面试题 class Value public int i 15 public class Test public static void mainString args Test t new Test t.first public void first int i 5 Value v new Value v.i 25 secondv i System.out.printlnv.i public void secondValue v int i i 0 v.i 20 Value val new Value 65 Java 程序员面试宝典(第
上一篇:
中国司法改革中的程序正义【精品论文】
下一篇:
ASP小区停车管理系统(Access)(含录像)