zoukankan      html  css  js  c++  java
  • 引用

    转载:https://www.cnblogs.com/shoshana-kong/p/10822538.html

    指针是一种变量,其中存储了地址信息,可以操作其中的地址来变换指针指向的变量,也可以进入其中的地址来修改被指变量本身。Java中去除了指针的概念,使用引用这个概念。

    引用是什么

    package chapter3Demos;
    
    import source.Hero;
    
    public class Demo3_3_2 {
    
        public static void main(String[] args)  {
            Hero h = new Hero();
            System.out.println(h);
        }
        
    }

    打印结果source.Hero@15db9742

    我们知道,在new一个对象时,new返回了一个新对象的引用,并将其存入等号左边的对象变量中。也就是说,h是一个Hero对象的引用。从上例我们不难发现,h中存储的是一个地址,也就是说本质上,引用也是指向对象的指针,但是只能操作对象本身,不能更改指针的指向,也没有了内存泄漏的危险。

    引用的细节

    既然引用中存储的是对象的地址,那么当有两个引用指向一个对象时,更改对象的状态,两个引用都会变化吗?

    package chapter3Demos;
    
    import source.Hero;
    
    public class Demo3_3_2 {
    
        public static void main(String[] args)  {
            Hero h = new Hero();
            System.out.println(h.getHp());
            Hero hero = h;
            h.setHp(4);
            System.out.println("h的血量:"+h.getHp());
            System.out.println("hero的血量:"+hero.getHp());

          System.out.println(h);
          System.out.println(hero);

    
        }
    }

    打印结果:

    5
    h的血量:4
    hero的血量:4

     source.Hero@15db9742
     source.Hero@15db9742

    我们可以看到,这段代码先声明了h作为一个新hero的引用,然后把h的值赋给了hero,当我们改变h中hp的值时,通过hero打印出的hp也发生了变化。且打印h和hero中存储的内容得到的是相同的地址内容。所以我们可以判断,h和hero指向了同一个Hero对象,同一块内存空间。相当于一台电视机,先有了一个遥控器h,又复制了另一个遥控器hero。

    下面是另一个实例

    String cat1="little cat";
    String cat2="little cat";
    String cat3=new String("little cat");
    System.out.println(cat1==cat2);
    System.out.println(cat1==cat3);
    ————————————————
    版权声明:本文为CSDN博主「华-山」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/mountain_hua/article/details/88777672

    打印结果:

    true
    false

    我们先创建了一个cat1,并且内存中也有“little cat”了,这个时候如果用这种方式String cat2="little cat"创建cat2的话,Java虚拟机就会发现内存中已经存在“little cat”这个对象了(当然在创建cat1时也会检查内存中有没有“little cat”),就会直接把cat2指向“little cat”所在内存。所以cat1和cat2是指向同一个对象的引用,他们当然相等啦。

    然鹅,由于cat3的创建方式是通过new String("little cat")来创建的,这个时候就会在内存区域(准确的说是堆内存中)中新开辟一块内存空间创建对象“little cat”,与cat1操纵的对象在不同的内存地址(尽管内容相同)。cat1与cat3就是指向不同内存地址的遥控器(引用)了,当然不相等啦。

     

    引用传递和按值传递的区别

    public class ReferencePkValue2 {
         
        public static void main(String[] args) { 
            ReferencePkValue2 t = new ReferencePkValue2(); 
            int a=99; 
            t.test1(a);//这里传递的参数a就是按值传递 
            System.out.println(a);
             
            MyObj obj=new MyObj(); 
            t.test2(obj);//这里传递的参数obj就是引用传递
            System.out.println(obj.b);
        } 
         
        public void test1(int a){ 
            a=a++;
            System.out.println(a);
            } 
         
        public void test2(MyObj obj){ 
            obj.b=100;
            System.out.println(obj.b);
            }
    }

    输出是

    99
    99
    100
    100

    可以看到,int值没有发生变化,但是在test2方法中对obj类做的修改影响了obj这个对象。

    这里要特殊考虑String,以及Integer、Double等几个基本类型包装类,它们都是immutable类型,
    因为没有提供自身修改的函数,每次操作都是新生成一个对象,所以要特殊对待,可以认为是和基本数据类型相似,传值操作。

    结合上面的分析,关于值传递和引用传递可以得出这样的结论:

    (1)基本数据类型传值,对形参的修改不会影响实参;
    (2)引用类型传引用,形参和实参指向同一个内存地址(同一个对象),所以对参数的修改会影响到实际的对象;
    (3)String, Integer, Double等immutable的类型特殊处理,可以理解为传值,最后的操作不会修改实参对象。

      参考https://www.cnblogs.com/menmenz/p/11756857.html

    看一个例子:

    1
    2
    3
    class MyObj{
        public int b=99;
    }

    分别传参int和对象类型:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    public class ReferencePkValue2 {
         
        public static void main(String[] args) { 
            ReferencePkValue2 t = new ReferencePkValue2(); 
            int a=99
            t.test1(a);//这里传递的参数a就是按值传递 
            System.out.println(a);
             
            MyObj obj=new MyObj(); 
            t.test2(obj);//这里传递的参数obj就是引用传递
            System.out.println(obj.b);
        
         
        public void test1(int a){ 
            a=a++;
            System.out.println(a);
            
         
        public void test2(MyObj obj){ 
            obj.b=100;
            System.out.println(obj.b);
            }
    }
  • 相关阅读:
    腾讯云通信 资料
    获取openid 的步骤
    微信公众号推送通知接口
    患者接收医生的消息通知完整流程(微信公众号的界面)
    阿里im即时通讯 h5 demo
    微信微信JS-SDK 6.0.2 填坑笔记
    2018秋季寒假作业1-介绍自己
    勿忘初心
    Ubuntu中安装eclipse
    vim的常用指令
  • 原文地址:https://www.cnblogs.com/Joey777210/p/11753476.html
Copyright © 2011-2022 走看看