精华内容
下载资源
问答
  • Java的引用和C++引用的区别

    千次阅读 2018-09-21 11:46:40
    java的引用并不是引用,而是隐藏的指针!!!要把java的引用当作指针来看!!! 而c++的引用才是真正的引用 java的引用只是能操作原内存,不能操作指向内存的指针,而c++的引用不仅是操作原内存,更是操作指向原内存...

    java的引用并不是引用,而是隐藏的指针!!!要把java的引用当作指针来看!!!

    而c++的引用才是真正的引用

    java的引用只是能操作原内存,不能操作指向内存的指针,而c++的引用不仅是操作原内存,更是操作指向原内存的指针!

    c++里对对象的引用相当于二级指针,而java里的引用只是一级指针

    new 类名();创建对象
    类名 xxx 创建对象的引用

    JAVA的引用反应到c里准确有三点

    类 string s = new string();

    一、java的引用实际上是个一级指针,

    在使用new的对象对其赋值时,new的对象省略了&,平时使用java的引用时省略了*即真实应该是string * s1 = new string(); string * s2 = new string();

    二、在对象的引用之间互相赋值时,都是赋的各自存储的地址值,

    即s1 = s2;也就说,java无法存在二阶指针,因为创建出来的实际上都是一级指针。而c++里一级指针的引用(当然实际上他是个二级指针),为 string * & s3 = s1;当*s3时可以修改s1所指向的内存,但引用的作用在于,他也可以修改s1所存储的地址,例s3 = new string();此时s1的地址也已经变化,总得来说

    c++的引用时高阶指针向低阶指针,而java引用是同阶指针指向同阶指针,总得来说其实都是一阶指针,故其实都是自身存储的地址值在相互间的传递,而不是将自身地址值赋给其他的指针

    故java中引用间互相传递可以更改所指向的共同内存,却无法更改各自所存储的地址值,即无法更改各自的引用所指向的方向

    展开全文
  • java的引用传递

    千次阅读 多人点赞 2017-01-13 21:01:49
    基础知识java的常用内存空间\color{red}{java的常用内存空间} 栈内存空间:保存所有的对象名称(更准确地说是保存了引用的堆内存空间的地址) 堆内存空间:保存具体对象的具体属性内容。 全局数据区:保存static类型...

    最近看着李兴华讲师的java视频教程学习java,关于java引用传递方面的知识的总结。


    基础知识

    java

    1. 栈内存空间:保存所有的对象名称(更准确地说是保存了引用的堆内存空间的地址)
    2. 堆内存空间:保存具体对象的具体属性内容。
    3. 全局数据区:保存static类型的属性
    4. 全局代码区:保存所有的方法定义

    实例分析

    class Person
    {
        private String name;
        private int age;
        private static String city = "北京";
        // 构造函数
        public Person(){}
        public Person(String name, int age)
        {
            this.name = name;
            this.age = age;
        }
    }
    
    public class Test
    {
        public static void main(String args[])
        {
            Person person = new Person("张三",20);
        }
    }

    以上产生的person对象的内存关系如下图:
    这里写图片描述


    javaString

    两种实例化方式

    1. 直接赋值: String str = “Hello”;
    2. 构造方法赋值 String str = new String(“Hello”);

    • 直接赋值:只开辟一块内存空间,字符串内容可以自动入池,供下次使用。
    • 构造方法赋值:开辟两块内存空间,有一块将成为垃圾,并且不能自动入池,需要使用intern()手动入池。

    实例代码分析

    #####直接赋值

    public class StringDemo
    {
        public static void main(String args[])
        {
            // 直接赋值
            String str1 = "Hello";
            // 直接赋值
            String str2 = "Hello";
            // 直接赋值
            String str3 = "Hello";
            System.out.println(str1 == str2);
            System.out.println(str1 == str3);
            System.out.println(str2 == str3);
        }
    }

    程序运行结果:
    true
    true
    true


    由程序执行结果可知:str1、str2、str3 3个字符串的内存地址完全相同,也就是说,实际上只开辟了一段堆内存空间。
    内存分析图:
    这里写图片描述


    #####构造方法赋值

    public class StringDemo
    {
        public static void main(String args [])
        {
            // 构造方法赋值
            String str1 = new String("Hello");
            // 构造方法赋值
            String str2 = new String("Hello");
            System.out.println(str1 == str2);
        }
    }

    程序结果:
    false


    由程序执行结果可知:str1、str2、 2 个字符串的内存地址不相同,也就是说,使用构造方法实例化的String类对象内容不会保存在字符串对象池中,即不能狗进行共享数据操作。


    构造方法赋值分析
    由于每一个字符串都是一个String类的匿名对象,所以首先会在堆内存中开辟一段内存空间保存字符串”Hello”,而后又使用关键字new开辟了另一块内存空间,并把之前定义的字符串常量的内存空间的内容赋给new开辟的空间,而此时之前定义的字符串常量的内存空间将不会有任何栈内存指向,就成成为垃圾,等待垃圾收集器(GC)不定期回收。


    内存分析图:
    这里写图片描述

    由上述的结论还可以知道:


    代码实例分析:

    public class TestDemo
    {
        public static void main(String args [])
        {
            String str = "Hello ";
            String str1 = "Hello ";
            String str2 = "Hello ";
            // str、 str1指向同一块内存空间
            System.out.println(str == str1 && str1 == str2) ;
            str += "World";
            // str和str2是否仍指向同一块内存空间
            System.out.println(str == str1)  ;
            System.out.println(str1 == str2)  ;
            System.out.println("str = " + str) ;
            System.out.println("str1 = " + str1);
        }
    }

    程序运行结果:
    true
    false
    true
    str = Hello World
    str1 = Hello
    str2 = Hello


    由程序执行结果可知,开始str、str1和str2指向同一块堆内存空间,改变str(连接”World”)之后,str指向的堆内存空间发生改变,而原str所指的堆内存空间的内容没有发生改变。


    内存分析图
    这里写图片描述

    java

    引用传递的本质是:


    代码实例分析


    范例一(自定义类对象作为函数参数传递)

    class Demo
    {
        private int data = 10;
        public Demo(){}
        public Demo(int data)
        {
            this.data = data;
        }
        public int getData()
        {
            return this.data;
        }
    }
    public class TestDemo
    {
        public static void main(String args [])
        {
            Demo demo = new Demo(100);
            fun(demo); // 等价于Demo temp = demo
            System.out.println(demo.getData());
        }
        public static void fun(Demo temp)// 接受引用
        {
            temp.setData(30);// 修改属性内容
        }
    }

    程序运行结果:
    30


    结果分析
    本程序首先在主方法中实例化了一个Demo对象,同时为类中的data属性赋值为100,之后将类对象传递给fun()方法由于类本身属于引用数据类型,所以fun()方法中的修改直接影响原始对象的内容。


    内存关系图
    这里写图片描述


    范例二(String类对象作为函数参数传递)

    public class TestDemo
    {
        public static void main(String args [])
        {
            String str = "Hello";  // 自定义字符串
            fun(str); // 引用传递: String temp = str
            System.out.println(str);
        }
        public static void fun(String temp)
        {
            temp = "World";
        }
    }

    程序运行结果:
    Hello


    通过程序运行结果可以发现,由于String类的内容不可变,所以当修改字符串数据(temp = “World”;)时就发生一个引用关系的变更,temp将指向新的堆内存空间。由于temp数据是方法的局部变量,所以方法执行完毕后,原始的str对象内容并不会发生任何改变。所以使用String类作为引用操作类型操作,关键是:String



    可以把String类看成基本数据类型。由于基本数据类型本身不牵扯到内存关系,而且传递时也只是值传递,不是内存地址传递,这样的特点是:方法里不管做何种修改,都不会影响原数据的内容。


    内存关系图
    这里写图片描述


    范例三(包含String类属性的自定义类作为函数参数传递)

    class Demo
    {
        private String data;
        public Demo(){}
        public Demo(String data)
        {
            this.data = data;
        }
        public void setData(String data)
        {
            this.data = data;
        }
        public String getData()
        {
            return this.data;
        }
    }
    
    public class  TestDemo
    {
        public static void main(String args [])
        {
            Demo demo = new Demo("Hello"); // 对象实例化
            fun(demo); // 引用传递:Demo temp = demo
            System.out.println(demo.getData());
        }
        public static void fun(Demo temp)
        {
            temp.setData("World");
        }
    }

    程序运行结果:
    World


    本程序和范例一从本质上将没有本质上的区别,唯一的区别在于本次使用了String作为Demo类的属性。如果把String类看成基本数据类型,可以得到如下内存分析图:
    这里写图片描述
    但实际上,更完整的内存关系应该表示为“Demo对象(栈)中包含了String的引用(data是String的名字存储在栈,而字符串的内容则存储在堆),Demo对象的堆内存中保存着data(栈内存)的引用关系”,完整的内存关系图如下:
    这里写图片描述

    展开全文
  • Java的引用队列和虚引用

    千次阅读 2019-06-23 15:50:40
    当联合使用软引用、弱引用和引用队列时,系统在回收被引用的对象之后,将把它所回收对象对应的引用添加到关联的引用队列中。而虚引用在对象被释放之前,将把它对应的虚引用添加到它关联的引用队列中,这使得可以在...

    一 点睛

    引用队列由ReferenceQueue类表示,它用于保存被回收后对象的引用。当联合使用软引用、弱引用和引用队列时,系统在回收被引用的对象之后,将把它所回收对象对应的引用添加到关联的引用队列中。而虚引用在对象被释放之前,将把它对应的虚引用添加到它关联的引用队列中,这使得可以在对象被回收之前采取行动。

    虚引用无法获取它所对应的对象。

    二 实战

    1 代码

    import java.lang.ref.*;
    
    public class PhantomReferenceTest
    {
       public static void main(String[] args)
          throws Exception
       {
          // 创建一个字符串对象
          String str = new String("疯狂Java讲义");
          // 创建一个引用队列
          ReferenceQueue rq = new ReferenceQueue();
          // 创建一个虚引用,让此虚引用引用到"疯狂Java讲义"字符串
          PhantomReference pr = new PhantomReference (str , rq);
          // 切断str引用和"疯狂Java讲义"字符串之间的引用
          str = null;
          // 取出虚引用所引用的对象,并不能通过虚引用获取被引用的对象,所以此处输出null
          System.out.println(pr.get());  //①
          // 强制垃圾回收
          System.gc();
          System.runFinalization();
          // 垃圾回收之后,虚引用将被放入引用队列中
          // 取出引用队列中最先进入队列中的引用与pr进行比较
          System.out.println(rq.poll() == pr);   //②
       }
    }

    2 运行

    null
    true

    3 说明

    使用引用类可以避免在程序执行期间将对象留在内存中。如果以软引用、弱引用或虚引用的方法引用对象,垃圾回收器就能够随意释放对象。如果希望尽可能减小程序在其生命周期中所占用的内存大小,这些引用类很有好处。

    展开全文
  • java的引用和C++的指针有什么区别

    千次阅读 2015-07-10 22:04:21
    大多数的C++程序员转学java的时候,都有这样一个疑问,java的引用就是C++的指针吗。其实不完全对,他们之间既有前四外绿的联系, 也有很大的区别。 java的引用和C++的指针都是指向一块内存址的,通过引用或者指针...

    大多数的C++程序员转学java的时候,都有这样一个疑问,java的引用就是C++的指针吗。其实不完全对,他们之间既有前四外绿的联系, 也有很大的区别。

    java的引用和C++的指针都是指向一块内存址的,通过引用或者指针完成对 内存数据的操作。就好像风筝的线轴一样,通过线轴总能够找到风筝。但是他们在实现、原理、作用等方面去有区别。

    (1)类型:引用其值为地址的数据元素,java封装了地址,可以转换成字符串查看,长度可以不必关心。C++指针是一个存放地址的变量,疮毒一般是计算机字长,可以认为是int。

    (2)所占内存:引用声明时没有实体,不占内存。C++如果声明后会用到才会赋值,如果用不到不会分配内存。

    (3)类型转换:引用的类型转换,也可能不成功,运行时抛异常或者编译就不能通过。C++指针只是个内存地址,指向哪里,对程序来说还都是一个地址,但可能所指的地址不是程序想要的。

    (4)初始化:引用初始化为java关键字null。C++指针是int,如不初始化指针,它的值就不固定了,这很危险。

    (5)计算:引用是不可以计算的。C++指针是int,它可以计算,如++ 或者--,所以经常用指针来代替数组下标。

    (6)控制:引用不可以计算。所以它只在自己的程序中,可以被控制。C++指针是内存地址,可以计算,所以他有可能指向一个不属于自己程序使用的内存地址,对于其他程序来说是很危险的,对自己程序来说也是不容易控制的。

    (7)内存泄露:java引用不会产生内存泄露。C++指针是容易产生内存泄露的,所以程序员要小心使用,即使回收。

    (8)作为参数:java的方法参数只传值,引用作为参数使用时,回给函数内引用的copy,所以在函数内交换两个引用参数是没有意义的,因为函数值交换参数的copy值,但在函数改变一个引用参数的属性是有意义的,因为引用参数的copy所引用的对象是和引用参数是同一个对象。C++指针作为参数给函数使用,实际上就是他所指的地址在被函数操作,所以函数内使用指针参数的操作都将直接作用到指针所指向的地址(变量、对象、函数等)

    本质上,他们两个都是想通过一个叫做引用或者指针的东西,找到操作的目标,方便在程序中操作。所不同的是java的办法更方便、安全一些,单失去了C++的灵活性,也算是对指针的一种包装和改进。

    展开全文
  • Java的引用和赋值

    千次阅读 2018-07-16 20:22:45
    2、Java赋值和引用很强大啊。。。如果是基本数据类型,那么是赋值,如果是引用数据类型,那么是引用(也就是两个变量指向同一个地址,改变其中一个,那么相应另外一个也相应变化)。所以说Java在传参时候,...
  • Java虽然有内存管理机制,但仍应该警惕内存泄露问题。例如对象池、缓存中过期对象都有可能引发内存泄露问题。 从JDK1.2版本开始,加入了对象几种引用级别,从而使程序能够更好控制对象生命周期,帮助...
  • java的引用类型所占用的内存空间

    万次阅读 2015-08-14 15:18:29
    Question:JAVA的引用的内存分配大小是多少? 如,我声明了一个对象,它在栈中就先有了个空间,(用来放地址引用的),这个空间的大小是多少? java规范中并没有强行定义虚拟机中任何一种类型在虚拟机中所占用...
  • Java的引用数据类型及应用

    千次阅读 2016-04-15 10:59:17
    Java的数据类型基本数据类型和引用数据类型的区别和联系:一、从概念方面来说基本数据类型:变量名指向具体的数值 引用数据类型:变量名指向存数据对象的内存地址,即变量名指向hash值二、从内存构建方面来说基本数据...
  • 引用的基本概念 强引用:当我们使用new创建对象时,被创建对象就是强引用,如Object object = new Object(),其中object就是一个强引用了。如果一个对象具有强引用,JVM就不会去GC它,JVM宁可会报OOM来终止程序...
  • 关于Java的引用和函数参数传递

    万次阅读 2006-12-02 20:46:00
    Java的语言设计者强调,这种不便可以通过Java的引用特性得到弥补。即对于Java的任何对象,我们可以申明对象变量,但不产生实例,这样,把该变量指向具有实际实例的对象,即可实现同一实例对象的多个变量引用,如:...
  • 有些程序员,认为java对对象采用引用调用,实际上这种理解是不对!!!       举例代码: 先写一个People类 package diaoYong; class People { private String name; public People(String str...
  • 赋值时,java会开辟一个新地址用于存放变量,而引用则不开辟地址。 String a = “a”; String b = “a”; 将String类实例化成对象a与b,并赋值 String c = new String(“a”); 将c指向new出来Stri...
  •  StrongReference 是 Java 默认引用实现, 它会尽可能长时间存活于 JVM 内, 当没有任何对象指向它时 GC 执行后将会被回收 @Test  public void strongReference() {   Object referent = new...
  • java参数传递(只有值传递没有引用传递)

    万次阅读 多人点赞 2019-07-31 19:25:14
    所以在java方法中改变参数值是不会改变原变量,但为什么改变引用变量属性值却可以呢?请看下面解答。 java数据类型 Java中数据类型分为两大类:基本类型和引用类型。相应,变量也分这两种类型:...
  • 什么是Java的对象引用? Java中都有哪些类型的对象引用? Java中提供的Java对象引用主要有什么目的? 通过本文,你就能很清楚得了解Java的对象引用
  • Java引用类型

    千次阅读 2016-03-16 19:12:55
    博主最近在整理Java集合框架时,在整理到WeakHashMap的时候,觉得有必要先阐述一下Java的引用类型,故此先整理的这篇文章,希望各位多提提意见。   闲话不多说,直接进入主题。Java中提供了4个级别的引用:强引用...
  • Java的引用

    千次阅读 2009-02-27 21:50:00
    java的引用其实更象c++中的指针,而非c++中的引用,的确c++的指针给我们带来强大威力的同时,也给我们带来了危险,大多的攻击也都是利用指针让系统崩溃。在许多书上都没有见到关于java中reference行为的更详细的探讨...
  • java引用和指针区别

    千次阅读 2018-05-15 17:50:13
    Java的引用和C++的指针的区别Java的引用和C++的指针都是指向一块内存地址的,通过引用或指针来完成对内存数据的操作,就好像风筝的线轴一样,通过线轴总是能够找到风筝,但是它们在实现,原理作用等方面却有区别。...
  • Java对象引用处理机制

    千次阅读 2013-11-13 11:31:17
    Java的引用别名机制(原文为Aliasing,别名,即Java中的多态)意味着多个引用变量可以定位到同一个实际物理对象,而这些引用变量可以是不同的类型. 下面的代码中,S类继承P类, pp 和 ss 分别是P类型 和 S类
  • Java引用类型参数也是值传递

    千次阅读 2019-03-14 20:28:13
    Java的引用类型作为参数传递给方法的时候,发生的仅仅是将引用类型变量的值复制一份给方法,让方法中的参数变量也指向内存中的对象区域。
  • JAVA 四中引用类型

    万次阅读 2019-07-09 12:22:12
    常见的java引用有四种:强引用、软引用、弱引用、虚引用; 下面分别来介绍一下各种引用: 1、强引用Java 中最常见就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用...
  • Java的引用和C++中引用的区别

    千次阅读 2015-08-16 12:44:20
    首先了解C++ 中引用的含义:“引用”即“别名”。C++中的引用代表的就是实际的存储空间。对其进行操作就是对存储空间进行操作。...Java的方法参数只是传值,引用作为参数使用时,会给函数内引用的值的COPY
  • Java引用类型有哪些

    万次阅读 2019-07-05 16:48:32
    其中,引用数据类型在存储堆中对需要引用的对象进行引用,引用是Java面向对象的一个特点,在Java入门中,我们会接触到四种Java的引用类型,接下来就说说这四种Java引用类型有哪些吧: 1、Java中有哪几种引用?...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 133,733
精华内容 53,493
关键字:

java的引用

java 订阅