• 关于java中是引用传递还是值传递的问题


    关于JAVA中参数传递问题有两种,一种是按值传递(如果是基本类型),另一种是按引用传递(如果是對象).
    首先以两个例子开始:
    1)
    public class Test2 {

    public static void main (String [] args) {
    StringBuffer a = new StringBuffer ("A");
    StringBuffer b = new StringBuffer ("B");
    operate (a,b);
    System.out.println(a+","+b);
    }

    static void operate(StringBuffer x, StringBuffer y){
    x.append(y);
    y = x;
    }
    }
    输出:AB,B

    2)
    public class Test2 {
    public static void add3 (Integer i){
    int val=i.intValue();
    val += 3;
    i = new Integer (val);
    }

    public static void main (String args [ ] ) {
    Integer i = new Integer (0);
    add3 (i);
    System.out.println (i.intValue ( ));
    }
    }
    输出:0
    首先我们应该明白JAVA中的参数传递全是以值传递的。是基本类型,就拷贝一个基本类型传进方法;是引用,就拷贝一个引用变量传进去方法,理解了这两点就能理解方法操作对象的相关问题了。最好能画出引用指向对象的图出来,就能完全理解了。
    第1题,调用operate方法时,传入了两个引用a,b的拷贝x,y,这两个x,y都指向原a,b引用所指向的对象。x.append(y)对它指向的对象(即a指向的对象)进行了操作。而x=y,只是两个拷贝变量在赋值,并没有影响到原b所指向的对象。所以b所指向的对象仍然为B。
    第2题,i=new Integer(val)只是一个引用的拷贝指向了另外一个对象,而原来的i仍然是指向对象new Integer(0)的。
    把握住了JAVA都是传值并且传的都是拷贝的话,类似的题大家都能迎刃而解了。



    Java中的参数传递只有一种方式: by value. 理论说教太麻烦了,直接看些例子吧:
    1). 基本类型
    public class A{
    public static void main(String[] args){
    int x = 1;
    System.out.println(x); //1
    test(x);
    System.out.println(x); //还是1==>By value
    }

    static void test(int a){
    a = 2;
    }
    }

    2). 引用类型
    public class B{
    public static void main(String[] args){
    Integer x = new Integer(1);
    System.out.println(x);
    test(x);
    System.out.println(x);

    }

    static void test(Integer a){
    a = new Integer(2);
    }
    }

    理解这里的关键是区分对象和引用。 这里声明的x是一个引用,而不是一个对象(只是Java把它设计为看上去好像是对象一样)。这个引用它指向了一个对象,这个对象就是后面用new关键字生成的对象。因此,可以说x指向了一个Integer对象。
    在调用test方法的时候,程序将x作为参数传递给test方法了。这里仍然是值传递,在test调用过程中,会产生一份新的引用(不妨叫做y)。此时,x和y指向了同一个对象。
    x和y指向的是同一个对象, 由于Java的设计,我们可以通过操作引用来达到操作对象的目的。因此,如果我们此时使用y来修改对象的属性 (例如,y.someField++); 你可以看到x指向的对象同时也被修改到了。
    另一方面,如果我们让y指向另外一个对象, y=new Integer(2); 此时x和y就指向了不同的
    对象。y修改了它指向的对象的属性,很显然不会影响到x指向的对象。



    有人说了数组。数组也是一个引用类型,它的参数传递方式按照引用类型的参数传递一样可以解释得通:

    import java.util.Arrays;

    public class A{
    public static void main(String[] args){
    int[] aa = {3, 2, 1};
    System.out.println(Arrays.toString(aa)); //[3, 2, 1]
    test(aa);
    System.out.println(Arrays.toString(aa)); //[3, 2, 1]
    test2(aa);
    System.out.println(Arrays.toString(aa)); //[4, 2, 1]
    }

    static void test(int[] a){
    a = new int[]{1, 2, 3}; //指向了新对象
    }

    static void test2(int[] a){
    if(a != null && a.length > 0)
    a[0]++; //修改原来的那个对象
    }
    }





    对象是传引用,简单类型是传值,不要被网上的一些概念所迷惑!!!你可以自己做个试验。
    至于String等类型传的还是引用。如果你用concat方法,String对象的原值就会被改变。
    但你如果按如下方法:
    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
    这里str = "World" 就等同于 String str=new String("World")。所以结果没有改变!!!

    下列程序在1处是否会有异常,如果没有,输出是什么?是否会运行到2处,如果会,输出是什么?为什么会有这样的结果?


      import java.util.arraylist;
       import java.util.list;
      
       public class testclass {


       public static void main(string args[]) {
         list list = new arraylist();
         test2(list);
         system.out.println(list.size()); // 1处
         test3(list);
         system.out.println(list.size()); // 2处
       }
      
       public static void test2(list list) {
         list = null;
       }
      
       public static void test3(list list) {
          list.add(“aaaa“);
       }
       }

    plumechen:

    不会出错的。结果是0,1。

    因为test2(list)传得是list的引用,我理解成指针置的副本,list=null;只是把那个传入的值设置为null,不改变原来list的指针和内容。test3(list)传入的一样,但是执行了list.add()由于传入指针值的副本也指向原来的那个list的地址,所以原来的那个list的内容就改变了,size变成了1了


    本文复制于:http://wenwen.sogou.com/z/q101054529.htm
  • 相关阅读:
    Wrong codepoints for non-ASCII characters inserted in UTF-8 database using CLP
    SqlException with message "Caught java.io.CharConversionException." and ERRORCODE=-4220
    XSD 数据类型
    Can't read [proguard.ClassPathEntry@1a0c10f] (No such file or directory)
    ubuntu 创建swap分区
    tar分层压缩
    MTK 自定义系统服务
    MTK framework系统默认设置
    MTK 修改默认屏幕亮度
    MTK 隐藏底部状态栏
  • 原文地址:https://www.cnblogs.com/I-will-be-different/p/3852186.html
Copyright © 2020-2023  润新知