精华内容
下载资源
问答
  • Java参数传递

    2016-04-05 19:34:45
    java参数传递

    java中所有的参数传递均是按值传递,是没有按引用传递的。
    基本数据类型毫无疑问传递的是数据值,而对象传递的也不是引用而是对象的地址值。

    展开全文
  • java参数传递

    2018-04-26 21:15:34
    java参数传递方式当一个对象被当作参数传递到一个方法后,在此方法内可以改变这个对象的属性,那么这里到底是值传递还是引用传递? 答:是按值传递。Java 语言的参数传递只有按值传递。当一个实例对象作为参数被传递...

    java参数传递方式

    当一个对象被当作参数传递到一个方法后,在此方法内可以改变这个对象的属性,那么这里到底是值传递还是引用传递?

    答:是按值传递。Java 语言的参数传递只有按值传递。当一个实例对象作为参数被传递到方法中时,参数的值就是该对象的引用的一个副本。指向同一个对象,对象的内容可以在被调用的方法内改变,但对象的引用(不是引用的副本) 是永远不会改变的。
    Java的参数传递,不管是基本数据类型还是引用类型的参数,都是按值传递,没有按引用传递!

    首先是定义改变参数的

        //改变int型变量的函数
        public static void changeInt(int i){
            i=100;
        }
        //改变String型变量的函数
        public static void changeString(String s){
            s="changeString";
        }
        //改变Model型变量的函数
        public static void changeModel(Model model){
            model=new Model();
            model.i=1;
            model.s="changeModel";
        }
        //改变Model型变量的成员的函数
        public static void changeModel2(Model model){
            model.i=1;
            model.s="changeModel";
        }

    类Model

         class Model{
             public int i=0;
             public String s="no value";
         }

    测试程序

         public static void main(String[]args) {
             int i=0;
             String s="hello";
             Model model=new Model();
             Model model2=new Model();
             changeInt(i);
             System.out.println("i="+i);
             changeString(s);
             System.out.println("s="+s);
             changeModel(model);
             System.out.println("model:"+model.s);
             changeModel2(model2);
             System.out.println("model2:"+model2.s);
    }

    测试结果:

    i=0
    s=hello
    model:no value
    model2:changeModel

    可以看出i没有改变,s也没有改变,mode也没有改变,model2的s改变了。

    基本数据类型

    public class TransferTest {
        public static void main(String[] args) {
            int num = 1;
            System.out.println("changeNum()方法调用之前:num = " + num);
            changeNum(num);
            System.out.println("changeNum()方法调用之后:num = " + num);
        }
    
        public static void changeNum(int x) {
            x = 2;
        }
    }

    运行结果:

    changeNum()方法调用之前:num = 1
    changeNum()方法调用之前:num = 1

    传递示意图:
    这里写图片描述

    num作为参数传递给changeNum()方法时,是将内存空间中num所指向的那个存储单元中存放的值1传递给了changeNum()方法中的x变量,而这个x变量也在内存空间中分配了一个存储单元,这个时候,就把num的值1传递给了x的这个存储单元中。此后,在changeNum()方法中对x的一切操作都是针对x所指向的这个存储单元,与num所指向的那个存储单元没有关系了!
    基本类型赋值时不会存储到内存。
    所以,在changeNum()方法调用之后,num所指向的存储单元的值还是没有发生变化,这就是所谓的“按值传递”!按值传递的精髓是:传递的是存储单元中的内容,而不是存储单元的引用!

    javabean类型

    public class TransferTest2 {
          public static void main(String[] args) {
              Person person = new Person();
              System.out.println(person);
              change(person);
              System.out.println(person);
          }
    
          public static void change(Person p) {
             p = new Person();
         }
     }
    
     /**
      * Person类
      */
    class Person {
    }

    两次打印person的地址值是一样的,即调用完change() 方法之后,person变量并没有发生改变。
    示意图如下:
    这里写图片描述

    当执行到第3行代码时,程序在堆内存中开辟了一块内存空间用来存储Person类的实例对象,同时在栈内存中开辟了一个存储单元用来存储该实例对象的引用,即上图中person指向的存储单元。

    当执行到第5行代码时,person作为参数传递给change()方法,需要注意的是:person将自己存储单元的内容传递给了change()方法的p变量!此后,在change()方法中对p的一切操作都是针对p所指向的存储单元,与person所指向的那个存储单元没有关系了!

    如果参数传递的是JavaBean,同时方法对这个参数的成员进行了修改,那么实参引用成员的值也会改变,因为他们的引用都指向同一个对象。

    参考

    java中的传递参数其实都是值传递(引用就是拷贝对象的一个地址)

    Java的参数传递是值传递还是引用传递

    展开全文
  • JAVA 参数传递

    2014-03-03 17:10:03
     网络上有太多关于JAVA参数传递是传值还是传引用的讨论,其实大多是概念不清,混淆视听。从程序运行的角度来看,参数传递,只有传值,从不传递其它的东西。只不过值的内容有可能是数据,也有可能是一个内存地址。 ...

    JAVA  参数传递


       

      网络上有太多关于JAVA参数传递是传值还是传引用的讨论,其实大多是概念不清,混淆视听。从程序运行的角度来看,参数传递,只有传值,从不传递其它的东西。只不过值的内容有可能是数据,也有可能是一个内存地址。

     Java中的数据类型有两大类,即基本类型(primitive types),共有8种,包括int, short, long, byte, float, double, boolean,char,存在于栈(Stack)中。另一种暂称为对象类型,包括Integer, String,Double等相应基本数据类型的包装类,以及其他所有JAVA自带和用户自定义的类,这些类数据全部存在于堆中(Heap),如下图所示。

      对象类型的数据不同于基本类型的数据,我们所定义的对象变量并不是对象实例本身,而是对象的一个引用(reference)地址,该内存地址用来定位该对象实例在HEAP中的位置。对象实例本身和对象的引用分别保存在HEAP和STACK中,对象引用和对象实例之间的关系好比遥控器和电视机之间的关系,在房间走动的时候里,你只需拿着遥控器就可以控制电视机,而不必带着电视机。而且,即使没有电视机,遥控器也可以独立存在,也就是说你可以定义一个对象类型的变量,但是可以暂时不和一个对象实例关联。多个对象引用也可以指向同一个对象实例。

     

              Heap(堆)      Stack(栈)
     JVM中的功能            内存数据区                   内存指令区
     存储数据  对象实例  基本数据类型, 指令代码,常量,对象的引用地址

     

    下面我们来看看几个例子,您就会更加明白。

    例子1:

    public class Test {
    public static void changeValue(int i) {
    i=2;
    System.out.println("during test: i = " + i);
    }
    public static void main(String[] args) {
    int i = 1;
    System.out.println("Before test: i = " + i);
    changeValue(i);
    System.out.println("After test: i = " + i);
    }
    }
      运行结果:
    Before test: i = 1
    during test: i = 2
    After test: i = 1

    不难看出,虽然在 changeValue(inti)方法中改变了传进来的参数的值,但对这个参数源变量本身并没有影响。其内部原理是,main方法里的变量和changeValue方法的参数是两个不同的变量,以参数形式传递简单类型的变量时,实际上是将参数的值作了一个拷贝传进方法的,那么在方法里再怎么改变其值,其结果都是只改变了拷贝的值,而不是源值。

    例子2:

    public class Test {
    public static void test(StringBuffer str) {
    str.append(", World!");
    }
    public static void main(String[] args) {
    StringBuffer string = new StringBuffer("Hello");
    test(string);
    System.out.println(string);
    }
    }
      运行结果:
    Hello, World!

      在这个例子里,似乎变量string被“改变”了。但其实改变的并不是string变量本身,也就是说string保存的内存地址并没有被改变,改变的是它所指向的对象实例。内部原理是这样的,在main方法里定义了一个对象引用string,并且把它和一个对象实例关联newStringBuffer。方法调用的时候,string所保存的对象实例的内存地址传递给了test方法的对象引用参数str,这时就有两个对象引用变量指向同一个对象实例。这两个对象引用都可以对该对象实例进行操作,操作结果都有效,因此在test方法执行完之后,对象实例的内容已经被改变了,这个时候再通过main方法里的string引用去查看对象实例的内容,看到的就是改变之后的内容。

    例子3:

    public class Test {
    public static void test(String str) {
    str = "World";
    }
    public static void main(String[] args) {
    String string = "Hello";
    test(string);
    System.out.println(string);
    }
    }

    运行结果:

    Hello。

    这个结果和上面结果矛盾吗?一点也不矛盾。在这个例子中,参数传递过程和上个例子完全一样,但是在test方法里并不是对原来指向的对象实例进行操作,而是把str指向了另外一个对象实例,当然对原来的对象实例毫无影响。


    转载地址:http://blog.sina.com.cn/s/blog_5dd380b90100bvel.html

    展开全文
  • java 参数传递

    千次阅读 2013-07-11 12:08:12
    由一个问题来引入参数传递的问题 public static void main(String[] args) { int x=1; int[] y =new int[10]; m(x,y); System.out.println("x is "+ x); System.out.println("y[0] is "+ y[0]); } public

    由一个问题来引入参数传递的问题

    public static void main(String[] args) {
    int x=1;
    int[] y =new int[10];
    m(x,y);
    System.out.println("x is "+ x);
    System.out.println("y[0] is "+ y[0]);
    }
    public static void m(int number , int[] numbers) {
    number=1001;
    numbers[0]=5555;
    }
    结果
    x is 1
    y[0] is 5555
    为什么x值未变y[0]变

    java变成语言的传参情况


      Java 编程语言只有值传递参数。

      Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言)。


      如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的 值不会改变原始的值.


      如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。

    根据理论我们来分析上面的那个问题

      现在你的问题就明确了.

      我们从内存角度来说明一下

      定义x的时候.

      变量x-->[存放值0]

      执行m(x,y)的时候;变量x将值0复制一份,并用number来指向

      变量number-->[存放复制的值0]

      这时再对number改变值为1.

      number-->[存放值1];

      此时,你会发现,该值number 跟 x是完完全全没有任何关系了.所以,你就可以理解为x为什么没有改变.


      下面说数组.

      定义y的时候.因为y是对象,所以y其实是一个地址指向真实的数组位置

      变量y-->[存放数组地址Y]

      执行m(x,y)的时候;变量y将值数组地址Y复制一份,并用numbers来指向

      变量numbers-->[复制的存放数组地址Y]

      此时,你会发现,该值numbers 跟 y其实是指向的同一个地址.也就是同一个对象.所以,你会发现赋值成功了

      其实,加入,你尝试下这段代码,你会发现更有趣的事情.

           

           public static void m(int number , int[] numbers) {
    		number=1001;
    		numbers = new int[10];
    		numbers[0]=5555;
    	}

      在这里.numbers就赋值失败了.想一想为什么?

      很简单.


      定义y的时候.因为y是对象,所以y其实是一个地址指向真实的数组位置

      变量y-->[存放数组地址Y]

      执行m(x,y)的时候;变量y将数组地址Y复制一份,并用numbers来指向

      变量numbers-->[复制的存放数组地址Y]

      执行new int[10] 并赋值地址给numbers的引用.

      变量numbers-->[new出来的数组的新地址]

      这时候你就发现.numbers的地址引用,和y的引用地址不同了.也就是说和变量number的效果是一样的了.故而赋值失败了.


    关于java的存储

    其实对于java来说,有人会很困惑,对象究竟是以什么形式存储的.之前的那个问题,究竟什么时候传递的是值,什么时候传递的是引用地址值.

    1.栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。

    2.栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

    3.Java中的数据类型有两种。

    i.一种是基本类型(primitive types), 共有8种,即int, short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。这种类型的定义是通过诸如int a = 3; long b = 255L;的形式来定义的,称为自动变量。值得注意的是,自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如int a = 3; 这里的a是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。(比较特殊的是String也会存放在栈中.)

    ii.另一种是包装类数据,如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中,Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。

    iii.String是一个特殊的包装类数据。即可以用String str = new String("abc");的形式来创建,也可以用String str = "abc";的形式来创建(作为对比,在JDK 5.0之前,你从未见过Integer i = 3;的表达式,因为类与字面值是不能通用的,除了String。而在JDK 5.0中,这种表达式是可以的!因为编译器在后台进行Integer i = new Integer(3)的转换)。前者是规范的类的创建过程,即在Java中,一切都是对象,而对象是类的实例,全部通过new()的形式来创建。Java 中的有些类,如DateFormat类,可以通过该类的getInstance()方法来返回一个新创建的类,似乎违反了此原则。其实不然。该类运用了单例模式来返回类的实例,只不过这个实例是在该类内部通过new()来创建的,而getInstance()向外部隐藏了此细节。那为什么在String str = "abc";中,并没有通过new()来创建实例,是不是违反了上述原则?其实没有。


    在java传递的参数中,什么是字面值,什么是地址值呢?

    其实很简单,基本类型的传递的均是字面值.也就是说直接存放于栈中的值.
    而Double,Integer等  , 以及用户自定义的各种Object均传递的是对象地址.因为他们存在于堆中.不同的只是Double和Integer都是无法改变的类型.你只能通过重新new Integer来改变值,这样,地址依然会变化,同样不能改变mian方法中的值.

    为什么说java是值传递.

    我们可以看到,java传递的对象全是栈中的值.java通过这种方法避过了指针.我们可以比较下
    c中,会有这样的参数传递   Dog *d   , 而在java 中是没有的 仅仅是 Dog d.也就是说,java中没有单独定义这种类型.虽然实际传递的也是地址.但是,在java中没有引用的这种说法.避免了我们自己去定义(我觉得这种思想就和垃圾回收一样,不需要我们去定义一些东西....) 传递的是值还是引用.所以,这个问题,其实没什么太大的争论必要.只是了解一下即可. 
    展开全文
  • Java参数传递方式

    2014-08-14 08:45:05
    Java参数传递
  • C++参数传递和java参数传递对比
  • Java参数传递问题

    2015-07-22 18:46:06
    Java参数传递问题
  • Java参数传递机制

    2017-06-18 00:00:36
    Java参数传递机制在Java中,方法的参数传递都是值传递,在调用方法时,参数会被创建出一个副本,原本的值不会被改变。 可以理解为:基础数据类型的参数传递的是值; 引用数据类型的参数传递的地址。 对于基础...
  • 前两天,写程序时候,想传递一个数组名给一个函数,然后给数组new一下,并初始化数据,这样就使用非return,获得了一个初始化过对象,但是运行程序报“NullPointerException”。这是为什么???代码如下:public ...
  • Java参数传递方式分为两种:值传递和引用传递 Java基本数据类型都是值传递方式,非基本数据类型(即引用类型,String除外,下面会详细介绍)是引用传递方式。 下面举例介绍: 1、基本数据类型及其包装类 public ...
  • “Java的参数传递到底是值传递还是引用传递?”这个问题在网上一直有... ★ “拷贝”是Java参数传递的核心所在!只要搞清楚“拷贝”是如何在参数传递中发挥作用的,那么“值传递还是引用传递”这个问题将迎刃而解。 参
  • Java参数传递——值传递还是址传递? 首先是变量的存储方式 各种变量的存储方式: 基本数据类型: int age = 20; 变量名age和值20都存储在jvm栈中 引用数据类型: 字符串见 ...
  • Java参数传递类型有几种

    千次阅读 2017-12-10 19:10:15
    Java参数传递类型 值,对象首地址
  • Java参数传递到底是传值还是传引用欢迎关注微信公众号:Java后台开发 Java中对象作为参数传递到底是传值还是传引用一直在网上饱受争议 首先来看基本类型作为参数传递 public class Test { public static void main...
  • 很多人再刚接触Java参数传递的时候,会一脸的问号????,到底参数是怎么传递的呢?我们首先要知道Java虚拟机中运行时数据区的分布情况: 虚拟机中各区域的作用 程序计数器:     程序计数器...
  • JAVA 参数传递 是值传递 还是引用传递的问题。 1 JAVA里面都是值传递 简单类型 boolean,byte, char, double ,float, integer, long, short 传递的是值副本,  对象传递的是对象的引用 2 对象类型中的简单类型的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 26,752
精华内容 10,700
关键字:

java参数传递

java 订阅