关于java中的参数传递

问题的引入是因为下午在群里看到了一个网友的问题:

给定如下Java 代码,编译运行后,输出结果是(  )。
public class Test {
    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;
    }
}
A. A,B    B. AB,B    C. A,AB     D.AB,AB

朋友可以猜猜这个答案,我也想告诉大家,答案是:B。也许有人会很惊讶,也许有人会很淡定。因为StringBuffer是一个类,对于类的使用,通过new,在堆中创建一个类的实例,利用一个引用来实现对这个对象的操作。当把一个引用当作参数传递到一个函数中的时候,C++采取的是:这个参数是一个地址。而在java中没有地址这个概念,一切都是值传递,那么这里又是怎么控制的。

首先,我做了一个测试: 

public class Text {

    public static void main(String[] args) {

        String s = "b";

        f(s);

        System.out.println(s);

    }

    static void f(String s) {

        s = "c";

    }

} /* output

b

*///~

从结果可以看出:形参的效果并没有作用到实参中。我们继续看下一段代码:

public class Text {

    String s = "b";

    public static void main(String[] args) {

        Text t = new text();

        f(t.s);

        System.out.println(t.s);

    }

    static void f(String s) {

        s = "c";

    }

} /* output

b

*///~

这里的输出结果还是为b。继续:

public class Text {

    String s = "b";

    public static void main(String[] args) {

        Txet t = new Text();

        f(t);

        System.out.println(t.s);

    }

    static void f(Text t) {

        t.s = "c";

    }

} /* output

c

*///~

从结果中可以看出:形参的效果作用到了实参,这里的引用发生了效果。

String为系统带的类,而Text为自定义的类,为了防止是自定义类跟系统类的影响,又使用了另外一个系统类List进行验证:

public class Text {

    public static void main(String[] args) {

        List<Integer> list = new ArrayList<Integer>();
        list.add(33);
        l(list);
        System.out.println(list);

    }

    static void l(List<Integer> list) {
        list.add(55);
    }

 

} /* output

[33, 55]

*///~

从输出结果中可以看出:类的引用效果得以发挥。

针对上面的结果,我想朋友们会有一些意外,因为在java基础语言学习中,我们曾经对“==”与“equals()”的操作曾经进行了很多的讨论,结果说明:String类是一个引用类型,给出一段代码,以供大家学习:

public class SimpleTypeText {

 public static void main(String[] args) {
      String s1 = "a";
      String s2 = "a";
      String s3 = new String("b");
      String s4 = new String("b");
      System.out.println("s1 == s2 ? " + (s1 == s2) );
      System.out.println("s1.equals(s2) ? " + s1.equals(s2)); 

      System.out.println("s2 == s3 ? " + (s2 == s3) );
      System.out.println("s2.equals(s3) ? " + s2.equals(s3));

      System.out.println("s3 == s4 ? " + (s3 == s4) );
      System.out.println("s3.equals(s4) ? " + s3.equals(s4));
  
      (s4, s1);
      }
      static void f(String s) {
          s = "a";
      }
      static void g(String s, String s1) {
          s = "a";
          System.out.println("通过常字符串:" + s == s1);
          s = new String(s1);
          System.out.println("通过new方法:" + s == s1);
      }
} /*output:

s1 == s2 ? true
s1.equals(s2) ? true
s2 == s3 ? false
s3.equals(s3) ? true
s3 == s4 ? false
s3.equals(s4) ? true
通过常字符串:true
通过new方法:false

*///~

 

总结:

1. thinking in java 中对String类型对象有这样一段描述:

 String对象是不可变的,没一个看起来会修改String值的方法,实际上都是创建了一个全新的String对象。

    对String类型的对象做参数有这样的一段描述:
每当把String对象作为方法的参数时,都会复制一份引用,而该引用所指的对象其实一直待在单一的物理位置上,从未动过。

2. 在字符串的声明中,利用常字符串初始化的时候,系统会从已有的常字符串进行查找,如果存在此字符串常量,则不再生成新的字符串常量,但是new方法不是这样的,即它不进行查找,直接开辟一段新的空间,存储这个字符串。

 

声明:以上代码均为参考,希望对基础有些帮助。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值