相信接触过C++的人,在学习Java的过程当中,会遇到这样一个问题:在Java中常常会在类定义中声明一个该类的对象(例如Person类定义中声明一些叫parents之类的Person对象),但是在C++中,这样的声明是会出现问题的。

例如,在C++中,如下的代码会出错:

class A
{
private:
A a;
};

而在Java当中,这样一段代码可以却可以使用:

class B{
private B b;
}

要理解这样一个问题,首先要知道的是,在Java中,只有基本数据类型和引用数据类型。对于一个类对象,都是使用引用的概念。而Java的引用和C++的引用是不同的,具体内容可以参考这篇博客 https://blog.csdn.net/WaitForFree/article/details/51030013 。

C++中的引用更像是一种“别名”(实质上是个指针常量),例如: Test & test2 = test1 ,test2就可以访问和修改test1内存中存储的内容。当改变test2的值时,改变的是存储在test1内存中的值。

Java中的引用实际上是一种隐藏的指针,例如:Test test2 = test1,这样的语句只是声明了一个名叫test2的引用,并将这个引用指向test1,可以通过test2这个名称访问test1内存中的值。但当改变test2的值时,是将test2这个引用指向一个新的位置,这一点类似于C++的指针。

在上面两段代码中,C++ 的A a是声明了一个A类对象,并为这个对象分配了内存空间,这就造成了无限递归创建对象,不停的分配内存空间,最后堆栈溢出。

而Java中引用数据类型的声明和分配内存是分开的,B b只是声明了B类的一个引用,并没有为它指定一个内存空间,因此不存在无限递归分配空间的问题。

而C++中的指针可以将声明和内存分配分开,因此,如果将上面那段C++代码改成指针形式,则不会出现问题:

class A
{
private:
A *a;
};

当然,如果在类声明中将指针指向new A()的内存空间,则还会出现堆栈溢出的问题。

同理,如果在Java中,为B的对象b new一个内存空间就会出错,此时Java会抛出一个异常。

class B{
private B b = new B();
}

所以,不论是Java还是C++,在实际使用过程中,如果想要在类定义中声明该类的一个对象,则应该使用引用/指针,且不能分配内存,否则在定义中无限递归分配内存会造成堆栈溢出的问题。

关于C++类定义中不能声明该类对象,而Java中可以的原因的更多相关文章

  1. java中replaceAll反斜杠\ or java中replaceAll 括号[

    java中replaceAll反斜杠\   String s=new String("this is a \\"); s.replaceAll("\\",&qu ...

  2. 用var声明变量,在java中居然有这么多细节,你都了解么?

    简介 Java SE 10引入了局部变量的类型推断.早先,所有的局部变量声明都要在左侧声明明确类型. 使用类型推断,一些显式类型可以替换为具有初始化值的局部变量保留类型var,这种作为局部变量类型 的 ...

  3. 类定义,创建/销毁OC对象

    类定义 1 OC类分为2个文件,一个是.h文件,一个是.m文件: 2 .h文件存放类.函数声明: 3 .m文件类的具体实现: 4 类声明使用关键字@interface.@end来声明: 5 类实现使用 ...

  4. Java中常用来处理时间的三个类:Date、Calendar、SimpleDateFormate,以及Java中的单例设计模式:懒汉式、饿汉式以及静态内部类式

    (一)java.util.Date类 1.该类有一个long类型的属性:用来存放时间,是用毫秒数的形式表示,开始的日期是从1970年1月1号 00:00:00.    2.该类的很多方法都已经过时,不 ...

  5. angularjs中directive声明scope对象的用法

    总的来说用法 分三种: >1: scope: false  --> 继承父域,实现 双向数据绑定 示例代码 可自测: <!DOCTYPE html> <html lang ...

  6. JSP中的内置对象和Struts中的Web资源的详解

    JSP中的内置对象有如下几种: request :继承于HttpServletRequest, HttpServletRequest继承ServletRequest, 获得的Request对象的方法: ...

  7. [hadoop] map函数中使用FileSystem对象出现java.lang.NullPointerException的原因及解决办法

    问题描述: 在hadoop中处理多个文件,其中每个文件一个map. 我使用的方法为生成一个文件,文件中包含所有要压缩的文件在HDFS上的完整路径.每个map 任务获得一个路径名作为输入. 在eclip ...

  8. python中print()函数的“,”与java中System.out.print()函数中的“+”

    python中的print()函数和java中的System.out.print()函数都有着打印字符串的功能. python中: print("hello,world!") 输出 ...

  9. 【问题记录】MySQL中时间戳转日期格式和Java中时间戳转日期格式偶尔不一致

    背景: MySQL的某个字段存放着一些时间戳格式的时间. 问题描述: Java程序将MySQL中的时间戳字段取出来,在Java程序中转成yyyy-MM-dd HH:mm:ss格式的时候,偶尔会出现转化 ...

随机推荐

  1. Java思考——HashSet集合如何保证元素的唯一性也就是不包含重复元素?

    首先将源码逐级找出来1.HashSet<String> hs=new HashSet<String>();         hs.add("hello"); ...

  2. mac安装git

    https://blog.csdn.net/shaock2018/article/details/91127607 继续报错 rm -rf /usr/local/Homebrew/Library/Ta ...

  3. switch语句能否作用在byte上,能否作用在long上,能否作用在String上?

    在Java 7以前,在switch(expr1)中,expr1只能是一个整数表达式(但不包括long和Long)或者枚举常量,整数表达式可以是int基本类型或Integer包装类型,byte.shor ...

  4. Zookeeper 对于 Kafka 的作用是什么?

    Zookeeper 是一个开放源码的.高性能的协调服务,它用于 Kafka 的分布式应用. Zookeeper 主要用于在集群中不同节点之间进行通信 在 Kafka 中,它被用于提交偏移量,因此如果节 ...

  5. 发现程序美----while+for冒泡实现的

    思想记录: 每一轮回的冒泡都将产生一个最大值,其后每次循环次数都将少一次,因为每次都会确定一个最大值. private void method(){ int[] list = {10,7,8,4,7, ...

  6. spring bean 容器的生命周期是什么样的?

    spring bean 容器的生命周期流程如下: 1.Spring 容器根据配置中的 bean 定义中实例化 bean. 2.Spring 使用依赖注入填充所有属性,如 bean 中所定义的配置. 3 ...

  7. OGNL(Object-Graph Navigation Language)使用

    OGNL表达式:https://www.jianshu.com/p/6bc6752d11f4 Apache OGNL:http://commons.apache.org/proper/commons- ...

  8. JavaScript 焦点事件

    焦点事件,当一个元素(比如链接或表单)得到或失去焦点时发生. 实例: 1 <!DOCTYPE html> 2 <html lang="en"> 3 < ...

  9. Anaconda 怎么安装cv2

    Anaconda run python程序的时候,如果有import cv2, 但是遇到报错的时候, 可以考虑在anaconda 中安装opencv, 安装过程非常简单. 什么是opencv , op ...

  10. 无需Flash实现图片裁剪——HTML5中级进阶

    前言 图片裁剪上传,不仅是一个很贴合用户体验的功能,还能够统一特定图片尺寸,优化网站排版,一箭双雕. 需求就是那么简单,在浏览器里裁剪图片并上传到服务器. 我第一个想到的方法就是,将图片和裁剪参数(x ...