Java按值传递和按址传递(面试常见)

先复制一个面试/笔试的题:

当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

答案:

是值传递。Java语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的。C++和C#中可以通过传引用或传输出参数来改变传入的参数的值。在C#中可以编写如下所示的代码,但是在Java中却做不到。

java中的按值传递和按址传递(按引用传递),要明白这两个概念,要理解按值和按址。

下面举个简单的例子来说明:

比如你去国外旅行,拍了一张特别好的照片,你想分享给你的朋友,那么有两种方式,第一种是你直接将这个照片发送给你的朋友,也就是给你朋友这个照片的副本;第二种是假如你将这张及其好的照片上传到一个QQ(微博)等,你将会得到一个访问这个照片的地址(Url),此时在将这个url分享给你的朋友。
如上例子,第一种可以认为是按值传递,第二种可以认为是按址传递(按引用传递)。知道了这个概念。在进行下面的简单分析。

按值传递:只有当参数为基本类型变量的时候,java按这种策略的方式传递。

上面的分享照片,你的朋友拿到的照片是你的副本,那么朋友对照片的修改不会影响你的照片,你对照片的修改也不会影响到你给朋友分享的照片。

按址传递:只有当参数为引用类型变量,java按这种策略方式进行传递。
上面的Url地址给朋友,那么如果朋友也有修改的权限,朋友对照片进行操作,自己访问的照片就是朋友操作结果后的结果。

下面通过代码来解释这个例子:

package com.dufy.reforvalue;
import java.util.Arrays;
/**
 * java中 按值传递和按址传递
 * 按值传递:基本类型变量-按值传递,按值传递通过复制获取参数的副本
 * 按址传递:引用类型变量-按址传递,按址传递通过传递对象的引用地址
 *
 * @author dufy
 * @creation 2017年2月9日
 */
public class ReferenceOrValue {
 /**
  * 基本类型,按值传递
  * 举例:给朋友分享你的照片,对方接收的是你的照片的一个实际的副本,
  * 你和朋友分别对各自的照片进行操作,不会影响彼此的照片!
  */
 public static void testVal(int photo){
  photo++;//朋友对照片进行修改
  System.out.println("My friend see photo = " + photo);
 }
 /**
  * 引用类型:按址传递
  * 举例:给朋友分享你的照片,分享的是你上传网上的一个照片的Url(地址),
  * 你和朋友都可以通过这个地址访问照片,并对照片进行一个操作!
  */
 public static void testRef(Photo photo){
  photo.setPhoto("java Photo,Great!");//朋友对你的照片进行修改
  System.out.println("My friend see photo = " + photo.getPhoto());
 }
 /**
  * 引用类型:按址传递
  * 因为数组是一个引用类型。所以传递进去的是它们的引用,故在方法中互换了它们的值,也必然影响到它们原来的值.
  */
 public static void testArrayRef(int[] array){
  for (int i = 0; i < array.length; i++) {
   array[i] = 0;
  }
  System.out.println("testArrayRef array is = "+Arrays.toString(array));
 }
 public static void main(String[] args) {
  //一:按值传递
  int photo = 10;//定义要发送的照片
  testVal(photo);//将照片发发送你朋友,朋友得到的是一个副本
  System.out.println("My see photo = " + photo);
  //二:按址传递
  Photo p = new Photo();//定义一个照片的对象,我自己拍摄的java photo
  p.setPhoto("java photo");
  testRef(p);//将照片对象(即 Url地址) 发送你朋友,朋友得打的是一个Url(地址),Url打开才是照片
  System.out.println("My friend see photo = " + p.getPhoto());
  //三:数组也是对象,数组在堆内存。引用是在栈。
  int array[] = {1,2,3,4,5};
  testArrayRef(array);
  System.out.println("array is = "+Arrays.toString(array));
 }
 /**
  * 照片类
  */
 static class Photo{
  String photo;
  public String getPhoto() {
   return photo;
  }
  public void setPhoto(String photo) {
   this.photo = photo;
  }
 }
}

输出的结果如下:

My friend see photo = 11
My see photo = 10
My friend see photo = java Photo,Great!
My friend see photo = java Photo,Great!
testArrayRef array is = [0, 0, 0, 0, 0]
array is = [0, 0, 0, 0, 0]

小插曲:有下下面这一道题:这个method应该怎么写呢?

public static void main(String[] args) {
  int a = 10;
  int b = 20;
  method(a,b);//需要在method被调用后,仅打印出a=100,b=200,请写出method(a,b)方法!
  System.out.println("a = " + a);
  System.out.println("b = " + b);
 }

肯定有很多人和我之前一样,想都没想就写出下面的代码:

private static void method(int a, int b) {
  a*=10;
  b*=10;
 }

但是运行结果后你会发现,没有打印出理想的结果!

这时候如果你仔细看来了上面的介绍就不难理解为什么会出现这样的结果了!

给出这道题可能正确的结果:

private static void method(int a, int b) {
  System.out.println("a=100,b=200");
  System.exit(0);
 }

以上所述是小编给大家介绍的Java按值传递和按址传递(面试常见),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

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

    java的值传递理解: 代码1: public class Test { /** * @param args */ public static void main(String[] args) { StringBuffer buffer= new StringBuffer("colin"); SChange(buffer); System.out.println( buffer); } public static void SChange (StringBuffer str) { st

  • 详解java的值传递、地址传递、引用传递

    详解java的值传递.地址传递.引用传递 一直来觉得对值传递和地址传递了解的很清楚,刚才在开源中国上看到一篇帖子介绍了java中的值传递和地址传递,看完后感受颇深.下边总结下以便更容易理解. 按照以前的理解,java中基本数据类型是值传递,对象是地址(引用)传递.给大家看个例子: public class ObjectTrans { public static void main(String[] args) { String name = "123"; SChange(name);

  • Java中的值传递和引用传递实例介绍

    复制代码 代码如下: package Object.reference; public class People {     private String name;     private int age;     public People(){     }     public People(String name, int age) {         super();         this.name = name;         this.age = age;     }    

  • 探讨Java中函数是值传递还是引用传递问题

    相信有些同学跟我一样,曾经对这个问题很疑惑.在网上也看了一些别人说的观点,评论不一.有说有值传递和引用传递两种,也有说只有值传递的,这里只说下个人见解 先给大家介绍下概念 值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响实际参数的值. 引用传递:(形式参数类型是引用数据类型参数):也称为传地址.方法调用时,实际参数是对象(或数组),这时实际参数与

  • Java值传递和引用传递详解

    当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递.Java 编程语言只有值传递参数.当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本.指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的. Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言). 如果参数类型是原

  • Java 值传递和引用传递详解及实例代码

     Java 值传递和引用传递 前言: 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递.Java 编程语言只有值传递参数.当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本.指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的. Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通

  • java中的值传递和引用传递的区别分析

    传值---传递基本数据类型参数 复制代码 代码如下: public    class           PassValue{    static void exchange(int a, int b){//静态方法,交换a,b的值        int temp;        temp = a;        a = b;        b = temp;    }    public static void main(String[] args){       int i = 10;   

  • Java按值传递和按址传递(面试常见)

    先复制一个面试/笔试的题: 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答案: 是值传递.Java语言的方法调用只支持参数的值传递.当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用.对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的.C++和C#中可以通过传引用或传输出参数来改变传入的参数的值.在C#中可以编写如下所示的代码,但是在Java中却做不到. java中的按值传

  • Java必备知识之位运算及常见进制解读

    目录 常见几种进制? Java八种按位运算? HashMap添加元素四步曲用到的位运算? 前奏:HashMap如何添加一个元素? 第一步曲 第二步曲 第三步曲 第四步曲 终曲:为什么HashMap底层源码用这么多位运算? 您好,我是贾斯汀,欢迎又进来学习啦! [学习背景] 学习Java的小伙伴,都知道想要提升个人技术水平,阅读JDK源码少不了,但是说实话还是有些难度的,底层源码实现的原理离不开各种常用的数据结构和算法,很多时候还会用到各种位运算,比如面试必问和工作写烂透了的HashMap,就一个

  • 解析C/C++值传递和址传递的区别

    C/C++的按值传递和按地址传递有明显不同,下面对他们作个区别: 按值传递:在调用函数中将原函数的值拷贝一份过去被调用的函数,在被调用函数中对该值的修改不会影响原函数的值. 按地址传递:在调用函数的时候将原函数的值所在的地址拷贝一份过去,被调用函数对这个地址所作的修改会影响原来的值. 概述: 首先我们要知道 "a的地址"和"a地址中的内容"的区别,数据是存放在内存中的,每一个变量都有一个内存地址, 变量的内容存放在对应内存地址的空间中 比方说定义 int a = 1

  • 从string类的实现看C++类的四大函数(面试常见)

    朋友面试的一道面试题,分享给大家,面试官经常会问到的,实现string类的四大基本函数必掌握. 一个C++类一般至少有四大函数,即构造函数.拷贝构造函数.析构函数和赋值函数,一般系统都会默认.但是往往系统默认的并不是我们所期望的,为此我们就有必要自己创造他们.在创造之前必须了解他们的作用和意义,做到有的放矢才能写出有效的函数. #include <iostream> class CString { friend std::ostream & operator<<(std::

  • 面试常见的js算法题

    我们去面试一般都有笔试,笔试题一般都会涉及到很多算法的东西. 不管你用的多不多,反正就是要会.不然笔试很难过. 就算是直接面试的,有时候也会遇到面试官直接叫你当场写个算法题出来这种情况. 因为笔试时间很有限,不会出很复杂的题目,所以笔试怎么出都不会离开下面这几种题. 废话不多说,下面来列出主要的几个算法题. 1.排序 一般都是给个数组然后排序,有的从小到大,有的从大到小.一定要看清楚.以下都是从小到大的排序算法. 冒泡法 var arr = [3,6,1,2,5]; var temp; for(

  • 一篇文章搞定JavaScript类型转换(面试常见)

    为啥要说这个东西?一道面试题就给我去说它的动机. 题如下: var bool = new Boolean(false); if (bool) { alert('true'); } else { alert('false'); } 运行结果是true!!! 其实啥类型转换啊,操作符优先级啊,这些东西都是最最基本的.犀牛书上有详细的介绍.但我很少去翻犀牛书的前5章... 比如说优先级那块儿,很多书都教育我们,"不用去背诵优先级顺序,不确定的话,加括号就行了."平常我们写代码时也确实这么做的

  • Java数组高级算法与Arrays类常见操作小结【排序、查找】

    本文实例讲述了Java数组高级算法与Arrays类常见操作.分享给大家供大家参考,具体如下: 冒泡排序 冒泡排序原理 冒泡排序代码: package cn.itcast_01; /* * 数组排序之冒泡排序: * 相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处 */ public class ArrayDemo { public static void main(String[] args) { // 定义一个数组 int[] arr = { 24, 69, 80, 57,

  • C++中引用传递与指针传递的区别(面试常见)

    最近Garena面试的过程中,面试官提了一个问题,C++中引用传递和指针传递的区别? 根据自己的经验,联想到了swap函数,只知道既可以用引用来实现,又可以用指针传递来实现,至于二者有何区别,自己还真没有考虑过. 痛定思痛,受虐之后,赶紧弥补自己的知识漏洞. 通过在网上搜集资料,自己也整理了一下. 精简版: 指针:变量,独立,可变,可空,替身,无类型检查: 引用:别名,依赖,不变,非空,本体,有类型检查: 完整版: 1. 概念 指针从本质上讲是一个变量,变量的值是另一个变量的地址,指针在逻辑上是

  • 使用Vue如何写一个双向数据绑定(面试常见)

    1.原理 Vue的双向数据绑定的原理相信大家也都十分了解了,主要是通过 Object对象的defineProperty属性,重写data的set和get函数来实现的,这里对原理不做过多描述,主要还是来实现一个实例.为了使代码更加的清晰,这里只会实现最基本的内容,主要实现v-model,v-bind 和v-click三个命令,其他命令也可以自行补充. 添加网上的一张图 2.实现 页面结构很简单,如下 <div id="app"> <form> <input

  • Java异常(Exception)处理以及常见异常总结

    目录 前言 异常简介 异常类型 总结 前言 很多事件并非总是按照人们自己设计意愿顺利发展的,经常出现这样那样的异常情况.例如: 你计划周末郊游,计划从家里出发→到达目的→游泳→烧烤→回家.但天有不测风云,当你准备烧烤时候突然天降大雨,只能终止郊游提前回家."天降大雨"是一种异常情况,你的计划应该考虑到这样的情况,并且应该有处理这种异常的预案. 计算机程序的编写也需要考虑处理这些异常情况.异常(exception)是在运行程序时产生的一种异常情况,已经成为了衡量一门语言是否成熟的标准之一

随机推荐