美文网首页学习Java学习笔记
Java的传值与传引用

Java的传值与传引用

作者: 黄言黄语 | 来源:发表于2016-06-25 00:01 被阅读1923次

    最近在工作中踩到了一个坑,就是Java的值传递和引用传递。对于值传递和引用传递定义有了解,但编写代码时没有特别注意。因为这个原因导致一个重大的线上bug,这个是不可原谅的。由此决定把这些内容再次牢记,记录下来。

    作为一个工作几年还犯这个错误真是太惭愧!!

    定义

    • 传值
      传递的是值的副本。方法中对副本的修改,不会影响到调用方
    • 传引用:
      传递的是引用的副本,共用一个内存,会影响到调用方。
      此时,形参和实参指向同一个内存地址。
      对引用副本本身(对象地址)的修改,如设置为null,重新指向其他对象,不会影响到调用方。

    基本数据类型

    public class ParamChangeValue {    
            public static void main(String[] args) {        
                int s = 1;        
                System.out.println("args = [" + s + "]");        
                change(s);        
                System.out.println("args = [" + s + "]");  
           }    
          private static void change(int i){ 
           i = i* 5;    
          }
    }
    

    输出

    args = [1]
    args = [1]
    

    对象

    public class ObjectChangeValue {    
      public static class Score{        
          private int value;        
          public int getValue()  {            
              return value;  
           }        
        public void setValue(int value) {
                this.value = value;     
         }    
    }   
     public static void main(String[] args) {       
       Score score = new Score();        
        score.setValue(1);        
        System.out.println("args = [" + score.getValue() + "]");                       
        change(score);        
        System.out.println("after args = [" + score.getValue() + "]");    
      }    
      private static void change(Score score){  
          score.setValue(2);    
      }
    }
    

    输出

    args = [1]
    after args = [2]
    

    注:
    如果对象被重新创建或赋值为null,即new则会重新指向其他对象,不影响其远对象的值

    public class ObjectChangeValue {    
      public static class Score{        
          private int value;        
          public int getValue()  {            
              return value;  
           }        
        public void setValue(int value) {
                this.value = value;     
         }    
    }   
     public static void main(String[] args) {       
       Score score = new Score();        
        score.setValue(1);        
        System.out.println("args = [" + score.getValue() + "]");                       
        change(score);        
        System.out.println("after args = [" + score.getValue() + "]");    
      }    
      private static void change(Score score){  
          score = new score();    
      }
    }
    

    输出

    args = [1]
    after args = [1]
    

    String、Integer、Long等

    public class StringChangeValue {    
        public static void main(String[] args) {        
              String s = "test1";        
              System.out.println("args = [" + s + "]");        
              change(s);                
              System.out.println("args = [" + s + "]");    
        }    
        private static void change(String i){       
               i = i + " test value";    
        }
    }
    

    输出

    args = [test1]
    args = [test1]
    

    总结

    1. 基本类型(byte,short,int,long,double,float,char,boolean)为传值
    2. 对象类型(Object,数组,容器)为传引用
    3. String、Integer、Double等immutable类型因为类的变量设为final属性,无法被修改,只能重新赋值或生成对象。
      当Integer作为方法参数传递时,对其赋值会导致原有的引用被指向了方法内的栈地址,失去原有的的地址指向,所以对赋值后的Integer做任何操作都不会影响原有值。

    相关文章

      网友评论

      本文标题:Java的传值与传引用

      本文链接:https://www.haomeiwen.com/subject/suzodttx.html