java学习——java按值传递和按址传递

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

大家好,又见面了,我是全栈君。

看这篇也可以看一下最新整理的文:

Java内存管理-Stackoverflow问答-Java是传值还是传引用?(十一)

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

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

答案:

是值传递。Java语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的。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);
	}

附:

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);
		System.out.println("a = " + Integer.valueOf(a));
		System.out.println("b = " + Integer.valueOf(b));
	}

	private static void method(Integer a, Integer b)  {
		try {
			Field filea = a.getClass().getDeclaredField("value");
			filea.setAccessible(true);
			filea.setInt(a, 100);
			Field fileb = b.getClass().getDeclaredField("value");
			fileb.setAccessible(true);
			fileb.setInt(b, 200);
			
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private static void method1(int a, int b) {
		System.out.println("a=100,b=200");
		System.exit(0);
	}

输出结果:

a = 10
b = 20
a = 100
b = 200

你觉得正确的答案是什么,可以给我留言和评论,欢迎讨论!

java到底是值传递还是引用传递? 知乎:https://www.zhihu.com/question/31203609
你会swap吗,按值传递还是按引用?:http://www.cnblogs.com/foreach-break/p/call-by-reference-OR-call-by-value.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/121191.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 取反!和按位取反~的区别[通俗易懂]

    取反!和按位取反~的区别[通俗易懂]按位取反“~”:按位取反1变0,0变1逻辑非“!”:逻辑取反,false变true,true变false,在C中,只要不是0就是真——————————————————————————————————————————

    2022年8月15日
    5
  • 程序员们千万不要接私活(程序员找私活的平台)

    点击上方“码农突围”,马上关注,每天上午8:50准时推送这里是码农充电第一站,回复“666”,获取一份专属大礼包真爱,请设置“星标”或点个“在看”作者:程序员新视界来源:…

    2022年4月11日
    135
  • 【最佳网页宽度及其实现】「建议收藏」

    1.设计网页的时候,确定宽度是一件很苦恼的事。以minifun…

    2022年1月18日
    45
  • 计算机分子模拟聚乙烯,高分子物理实验思考题@中科大.pdf[通俗易懂]

    计算机分子模拟聚乙烯,高分子物理实验思考题@中科大.pdf[通俗易懂]高分子物理实验思考题@中科大1.为什么在计算机模拟实验1(用“分子模拟”软件构建全同立构聚丙烯分子、聚乙烯分子并计算它们末端的直线距离)中我们一再把第一个碳原子到最后一个碳原子的距离叫做末端距离,而不称通常所说的根均方末端距?2.你对计算机在高分子科学中的应用有多少了解?3.在考虑高分子链内旋转空间位阻时,高分子链的尺寸如何变化?4.在“二维高分子链形态的计算机模拟”实验中采用的是改进后…

    2022年5月25日
    30
  • hash冲突以及hash冲突的解决方法

    hash冲突以及hash冲突的解决方法首先说一下hash冲突吧,hash冲突在hash表中一般情况下是会遇到的;hash冲突指的是你在向hash表中存数据时,首先要通过key值进行指定的hash算法进行计算,然后得到一个值,这个值就是你要将这个key对应的value存入的地址。但是在这个地址中已经有值存在,所以这个时候就发生了hash冲突,不同的key通过hash算法得到了对应的同一个值。hash冲突解决的方法:再hash法:这种方法就是有多个hash算法,当使用一个hash算法计算得到值发生hash冲突时那就使用另外一个hash算法

    2022年10月8日
    0
  • ui ue设计是什么_ui设计师

    ui ue设计是什么_ui设计师设计在我们的生活中扮演着重要的角色,但是面对越来越多的专业术语和相近的岗位职责,人们总是困惑:明明是差不多的岗位,为什么要整那么多的词。UI、UE、UID、UED相信很多人都弄不清楚这些名字是什么意思,到底有什么区别。其实,在它们神似的外表下,潜藏着巨大的差异。本文,就来详细说说UI设计和UE设计这是两种概念,以及如何将它们区分开来。一、UI、UE的定义1、UI:UserInterface…

    2022年4月19日
    76

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号