突然想到这个问题,然后做了下实验,下面以Integer来讲解,其他的忽略:

import java.util.Iterator;

/**
* Created by lili on 15/9/24.
*/
public class TestNew {
public static void main(String args[]){ Integer i1 = 10;
Integer i2 = 20;
System.out.println(i1 + " " + i2);
change(i1,i2);
System.out.println(i1 + " " + i2); String s1 = new String("s1");
String s2 = new String("s2");
System.out.println(s1 + " " + s2);
change(s1, s2);
System.out.println(s1 + " " + s2); StringBuilder sb1 = new StringBuilder("sb1");
StringBuilder sb2 = new StringBuilder("sb2");
System.out.println(sb1 + " " + sb2);
change(sb1,sb2);
System.out.println(sb1 + " " + sb2); } public static void change(Integer i1, Integer i2){
i1 = 100;
i2 = 200;
} public static void change(String i1, String i2){
i1 = "ii1";
i2 = "i22";
} public static void change(StringBuilder i1, StringBuilder i2){
i1.append("sbsbsb1");
i2.append("sbsbsb2");
}
}

运行结果:

10   20
10 20
s1 s2
s1 s2
sb1 sb2
sb1sbsbsb1 sb2sbsbsb2 Process finished with exit code 0

事实证明,只有StringBuilder是引用传递,其他的还是值传递。

按照常理,应该传递的是对象的地址,难道这里是因为做了自动装箱和拆箱,编译器帮你做了这个导致最后是值传递了?

带着这个问题首先去看了class文件的反编译代码:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// public class TestNew {
public TestNew() {
} public static void main(String[] var0) {
Integer var1 = Integer.valueOf(10);
Integer var2 = Integer.valueOf(20);
System.out.println(var1 + " " + var2);
change(var1, var2);
System.out.println(var1 + " " + var2);
String var3 = new String("s1");
String var4 = new String("s2");
System.out.println(var3 + " " + var4);
change(var3, var4);
System.out.println(var3 + " " + var4);
StringBuilder var5 = new StringBuilder("sb1");
StringBuilder var6 = new StringBuilder("sb2");
System.out.println(var5 + " " + var6);
change(var5, var6);
System.out.println(var5 + " " + var6);
} public static void change(Integer var0, Integer var1) {
var0 = Integer.valueOf(100);
var1 = Integer.valueOf(200);
} public static void change(String var0, String var1) {
var0 = "ii1";
var1 = "i22";
} public static void change(StringBuilder var0, StringBuilder var1) {
var0.append("sbsbsb1");
var1.append("sbsbsb2");
}
}

源代码显示并没有做值传递的优化,因为如果做了,应该change中的参数会改为int,这样一来Integer对象会自动拆装为int进行值传递,一种自动装卸拆箱的代码示例如下:

 Integer integer = 11;
integer += 9; /*
Integer integer = Integer.valueOf(11);//自动装箱
integer = Integer.valueOf((integer.intValue() + 9));//自动拆箱再装箱
*/

那究竟是什么原因呢?

带着这个问题,对程序进行了debug,看看传递的是否是对象地址。

进入change方法后,看地址的变化

发现传入的是地址值,change参数的i1和i2的对象指向Integer@417和Integer@418,说明指向和传入参数的同一个对象,传入的是地址。

接着执行方法change程序:

执行改变i1的值时,此时i1指向的对象改为了Integer@427,至此可以充分说明不是自动装箱和拆箱的问题了,但是究其原因,我的理解还是和这个相关,因为执行到这一步的时候是i1 = 100;但是具体编译器优化后做了自动装箱处理,var0 = Integer.valueOf(100);所以i1指向了Integer.valueOf(100)这个新产生的对象,所以最后和值传递的效果一样,不会改变调用该方法的参数的值。

【Java基础】基本类型的包装类作为参数传递是值传递还是引用传递的更多相关文章

  1. java中参数传递--值传递,引用传递

    java中的参数传递——值传递.引用传递   参数是按值而不是按引用传递的说明 Java 应用程序有且仅有的一种参数传递机制,即按值传递. 在 Java 应用程序中永远不会传递对象,而只传递对象引用. ...

  2. Java参数传递是值传递还是引用传递?

    当一个对象被当作参数传递到一个方法后,在此方法内可以改变这个对象的属性,那么这里到底是值传递还是引用传递? 答:是值传递.Java 语言的参数传递只有值传递.当一个实例对象作为参数被传递到方法中时,参 ...

  3. Java的参数传递是值传递还是引用传递?

    一.前言 首先先说结论,Java中方法参数传递方式是按值传递.如果参数是基本类型,传递的是基本类型的字面量值的拷贝.如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝. 接下来深入了解一 ...

  4. Java中引用类型变量,对象,值类型,值传递,引用传递 区别与定义

    一.Java中什么叫做引用类型变量?引用:就是按内存地址查询       比如:String s = new String();这个其实是在栈内存里分配一块内存空间为s,在堆内存里new了一个Stri ...

  5. java中方法的参数传递机制(值传递还是引用传递)

    看到一个java面试题: 问:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?  答:是值传递.Java 编程语言只有值传递参 ...

  6. java参数传递时到底是值传递还是引用传递

    java参数传递时到底是值传递还是引用传递(baidu搜集) 问”,很多人的BLOG里都引用这些面试题,最近因为工作内容比较枯燥,也来看看这些试题以调节一下口味,其中有一道题让我很费解. 原题是:当一 ...

  7. java基础 - 形参和实参,值传递和引用传递

    形参和实参 形参:就是形式参数,用于定义方法的时候使用的参数,是用来接收调用者传递的参数的. 形参只有在方法被调用的时候,虚拟机才会分配内存单元,在方法调用结束之后便会释放所分配的内存单元. 因此,形 ...

  8. Java是值传递还是引用传递?

    Java的值传递和引用传递在面试中一般都会都被涉及到,今天我们就来聊聊这个问题.这个问题一般是相对函数而言的,也就是Java中所说的方法参数,那么我们先来回顾一下在程序设计语言中有关参数传递给方法的两 ...

  9. 堆栈详解 + 彻底理解Java的值传递和引用传递

    本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ...

随机推荐

  1. FontDialog组件设置字体

    1.设置字体 private void button3_Click(object sender, EventArgs e) { this.fontDialog1.ShowDialog(); this. ...

  2. AngularJs项目

    AngularJs项目实践总结 今年3月接触AngularJs,并且在6月的项目中开始应用,从踩坑到填坑花了不少时间,根据项目中的实际应用情况总结了一些经验,如下: 一.UI控件选择 Angularj ...

  3. pywinauto简单介绍

    Pywinauto是基于Python开发的,用于自动化测试的脚本模块,主要操作于Windows标准图形界面.它可以允许你很容易的发送鼠标.键盘动作给Windows的对话框和控件. 其中,最主要功能为对 ...

  4. C# - 非中断(正常)模式下的调试

    一般我们用Console.WriteLine()函数,将文本输出到控制台上来跟踪代码进行到了什么位置,局限性很大,适用范围窄. 1. 输出调试信息 命名空间 System.Dignostics Deb ...

  5. windows10 Build 10074版本上手体验(二)

  6. Provider Communication with Apple Push Notification Service

    This chapter describes the interfaces that providers use for communication with Apple Push Notificat ...

  7. Matlab心得及学习方法(不断更新)

    Matlab心得及学习方法(不断更新) Matlab心得及学习方法(不断更新)P.S. 那些网上转载我的文章不写明出处的傻眼了吧?!老子更新了! 发现现在很多人(找工作的或者读博的)都想要学习或者正在 ...

  8. 程序不稳定是因为C++基础不扎实

    最近开发的程序,逻辑上都实现了,但是感觉运行不稳定,程序时不时崩溃(不是逻辑运行不正确),至少找出2个错误: 情况1:char* szRemoteReal = new char[MAX_LENGTH] ...

  9. LinuxShell_variable+if+while

    [root@ossec-server mybash]# vim ./hello.sh #! /bin/sh # This is a example bash script echo "Hel ...

  10. Styles and Themens(5)样式文件Style.xml中各元素的含义

    Style Resource See also Styles and Themes A style resource defines the format and look for a UI. A s ...