zoukankan      html  css  js  c++  java
  • Java中,String类型和包装类型作为参数传递时,是属于值传递还是引用传递呢?

    Java中,String类型和包装类型作为参数传递时,是属于值传递还是引用传递呢?

    原理知识:

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

    如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数。

    如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。


    String和包装类是什么类型传递这个问题,可能很多人都没有去细想过,下面我就给点我自己的见解。

    /**
     * 
     * @author ZHOUMI2
     */
    
    public class Test {
    
        public static void test1(Integer num){
            num = new Integer(5);
        }
    
        public static void test2(String str){
            str.replace("1", "4");
        }
    
        public static void main(String[] args) {
    
            Integer num = new Integer(1);
            test1(num);
            // 输出结果为1
            System.out.println(num.intValue());
    
            String str = new String("123");
            test2(str);
            // 输出结果为123
            System.out.println(str);
        }
    
    }
    分析:
    
        上述程序很容易让人误以为String类型和包装类型是值传递。
    
    其实我们认真想一下:
    
        String类型和包装类型都是对象类型,所以必然是引用传递    但是由于String类和包装类都没有提供value对应的setter方法,我们无法改变其内容,所以导致我们看起来好像是值传递。
    
    

    以下讨论Integer是引用传递还是值传递


    转自:http://www.tuicool.com/articles/AraaQbZ
    论integer是地址传递还是值传递

    Integer 作为传参的时候是地址传递 , 可以参考如下例子,在程序刚启动的时候把 Integer 的index 对象锁住 ,并且调用了 wait方法,释放了锁的资源,等待notify,最后过了5秒钟,等待testObject 调用notify 方法就继续执行了。大家都知道锁的对象和释放的对象必须是同一个,否则会抛出 java.lang.IllegalMonitorStateException 。由此可以证明 Integer作为参数传递的时候是地址传递,而非值传递。

    public class IntegerSyn {
    
      public static void main(String[] args) throws InterruptedException {
        Integer index = 0;
        TestObject a = new TestObject(index);
        synchronized (index) {
          new Thread(a).start();
          index.wait();
        }
        System.out.println("end");
      }
    }
    
    class TestObject implements Runnable {
      private Integer index;
    
      public TestObject(Integer index){
        this.index = index;
      }
    
      public void run() {
        try {
          TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        synchronized (index) {
          index.notify();
        }
      }
    }

     

    那就会有人问了,为什么执行如下代码的时候两次的输出结果是一样的?

    public static void main(String[] args) throws InterruptedException {
        Integer index = 0;
        System.out.println(index);
        test(index);
        System.out.println(index);
      }
    
      public static void  test(Integer index){
        index++;
      }

    理由很简单,可以看到 Integer 类中final的value字段,说明一旦integer类创建之后他的值就不能被修改在 index++ 的时候Integer是创建一个新的类,所以这个第二次输出的时候结果是一样的

    private final int value;
    • 1

    总结一下java中方法参数的使用情况:

    1. 一个方法不能修改一个基本数据类型的参数(即数值型和布尔型)
    2. 一个方法可以改变一个对象参数的状态
    3. 一个方法不能让对象参数引用一个新的对象

    在方法中一个引用指向了一个新的对象,只在方法中生效,出了方法,原来的引用内容是怎么样还是怎么样:
    Integer是不可变类,进入一个方法后,在里面的值的改变不会影响方法外的引用

     @Test
        public void testInteger() {
            Integer integer = new Integer(5);
            testchange(integer);
            //输出结果还是5
            System.out.println(integer);
        }
    
        private void testchange(Integer integer) {
            integer =new Integer(8);
            //这里输出结果是8
            System.out.println("方法里面的integer:"+integer);
        
  • 相关阅读:
    idea自动整理代码
    idea生成一个类的get/set/toStirng/构造函数等等方法
    idea生成一个java类Class
    解决eclipse不能下载最新的maven仓库中的jar包
    如何解决eclipse控制台信息显示不全
    tomcat-jdbc连接池配置
    三步教你安装微软系统,使用uiso制作U盘启动盘
    好用的java反编译 eclipse插件
    SpringBoot常用应用属性配置表
    SpringBoot的配置文件
  • 原文地址:https://www.cnblogs.com/shoshana-kong/p/13448459.html
Copyright © 2011-2022 走看看