1. 数组名区别

--------------------------------------

1. java中不用说,本着一切皆对象的原则,所以java中的数组也是对象.那么数组类是哪个,当然不是java.util.Arrays.详见Java数组方法的思考

2. 而在c++中数组名其实是一种数据结构,有人会说不是指针吗,关于这一点见(C++中数组名其实是一种数据结构)。

从上面两点中我们可以看出java数组名是对象,而c++数组名是数据结构。那么有人又会问对象和数据结构又有什么区别呢?详见数据结构与对象的区别

2. 原理区别

-----------------------------------

JAVA里数组的内存分配是在堆里面的,必须用new来分配,而C++里面是在栈里面分配的,定义的时候会自动分配。

java中的数组

1、数组不是集合,它只能保存同种类型的多个原始类型或者对象的引用。数组保存的仅仅是对象的引用,而不是对象本身。数组声明的两种形式:一、int[] arr; 二、int arr[];  推荐使用前者,这是一个int数组对象,而不是一个int原始类型。

2、数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。

4、在数组声明中包含数组长度永远是不合法的!如:int[5] arr; 。因为,声明的时候并没有实例化任何对象,只有在实例化数组对象时,JVM才分配空间,这时才与长度有关。

5、在数组构造的时候必须指定长度,因为JVM要知道需要在堆上分配多少空间。例:int[] arr = new int[5];

7、一维数组的构造。形如:String[] sa = new String[5];  或者分成两句:String[] sa;  sa = new String[5];

8、原始类型数组元素的默认值。对于原始类型数组,在用new构造完成而没有初始化时,JVM自动对其进行初始化。默认值:byte、short、 int、long--0  float--0.0f double--0.0  boolean--false  char--'"u0000'。(无论该数组是成员变量还是局部变量)

10、对象类型的数组虽然被默认初始化了,但是并没有调用其构造函数。(C++中则会调用)也就是说:Car[] myCar = new Car[10];只创建了一个myCar数组对象!并没有创建Car对象的任何实例!

11、多维数组的构造。float[][] ratings = new float[9][]; 第一维的长度必须给出,其余的可以不写,因为JVM只需要知道赋给变量ratings的对象的长度。

12、数组索引的范围。数组中各个元素的索引是从0开始的,到length-1。每个数组对象都有一个length属性,它保存了该数组对象的长度。(注意和String对象的length()方法区分开来)

13、Java有数组下标检查,当访问超出索引范围时,将产生ArrayIndexOutOfBoundsException运行时异常。注意,这种下标检查不是在编译时刻进行的,而是在运行时!也就是说int[] arr = new int[10];  arr[100] = 100; 这么明显的错误可以通过编译,但在运行时抛出!

Java中的数组中既可以存储基本的值类型,也可以存储对象。对象数组和原始数据类型数组在使用方法上几乎是完全一致的,唯一的差别在于对象数组容纳的是引用而原始数据类型数组容纳的是具体的数值。在讨论关于数组的问题时,一定要先确定数组中存储的是基本值类型还是对象。特别是在调试程序时,要注意这方面。

3. 类数组是否调用构造函数

-------------------------------------------------

对于上面提到的第10点对象类型的数组虽然被默认初始化了,但是并没有调用其构造函数。我必须要重点解释下,因为在c++中会调用其构造函数,这里最容易搞混。

  1. public class Test extends JPanel {
  2. private static final long serialVersionUID = 4767050156491994899L;
  3. public static void main(String[] args) {
  4. AnimApp[] array = new AnimApp[3]; // 没有执行构造函数, 在这里只是申请了空间.
  5. array[0] = new AnimApp(3); // 构造一个对象
  6. }
  7. }
  8. class AnimApp {
  9. public AnimApp(int times) {
  10. System.out.println("class AnimApp");
  11. }
  12. }

看下上面这段java代码,当执行AnimApp[] array = new AnimApp[3];时并不会调用构造函数,仅仅申请了空间。构造对象的时候才会调用构造函数。

Java中,定义一个数组, new[]时, 并没有执行构造函数, 只是申请了一段内存空间, 与C++中的allocator<T>.allocate(size)(因为allocator<T>的类型在运行时确定, 所以不是指定空间的字节数, 而是用元素个数, 每个元素的大小allocator中有记录)相似. 然后在构造一个对象的时候, 即如上new AnimApp(3)时, 才真正的构造对象, 似allocator<T>.construct(param).

C++中, new[]操作符(默认的)就会去先申请空间, 接着执行构造函数, 申请了多少个对象的空间, 执行多少次(每个对象一次), 所以想为无无参构造函数的类使用默认的new[]来定义一个数组是不行的, 这点与Java不同, 他是即申请空间, 同时也要构造对象, Java只是申请一段空间, 对于空间中的每个对象, 得自己显示的用new ClassName(param)来构造.

对于Java这种与C++不同之处的原因要归为它们之间的实现不同。

1)Java的数组不是集合,它只能保存同种类型的多个原始类型或者对象的引用。数组保存的仅仅是对象的引用,而不是对象本身。
2)数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
3)在Java中,官方推荐的声明方式是Object []array,并且不能指定长度,只有new的时候才指定长度。
4)对象类型数组中的引用被默认初始化为null。如:Object [] myobj= new Object [10]; 相当于从myobj[0]到myobj[9]都这样被自动初始化为myCar[i] = null;并没有调用构造函数。在myobj[1] = new Object的时候才调用。

至于Java为什么要选择这种方式,则是其刻意避免指针(容易犯错),符号都是引用类型。

几乎所有的程序设计语言都支持数组。在C和C++中使用数组是很危险的。因为C和C++中的数组就是内存块。如果一个程序要访问其自身内存块之外的数组,或者在数组初始化之前使用它,都会产生难以预料的后果。

java的主要目标之一就是安全性。java确保数组会被初始化,而且不能在它的范围之外被访问。这种范围检查,是以每个数组上少量的内存开销以及运行时的下标检查为代价的。但是由此换来的安全性和效率的提高,也是值得的。

当java创建一个数组对象时,实际上就是创建了一个引用数组,并且每个引用都会被自动初始化一个特殊值。该值拥有自己的关键字null,一旦java看见了null,就知道这个引用还没有指向某个对象。如果使用某个指向null的引用,就会在运行时报错。

Java/C++中数组的区别的更多相关文章

  1. Java集合和数组的区别

    参考:Java集合和数组的区别 集合和容器都是Java中的容器. 区别 数组特点:大小固定,只能存储相同数据类型的数据 集合特点:大小可动态扩展,可以存储各种类型的数据   转换 数组转换为集合: A ...

  2. Swift的数组与OC中数组的区别

    相同的值可以多次出现在一个数组的不同位置: Swift中的数组,数据值在被存储进入到某个数组之前类型必须明确,可以显示的类型标注或者类型推断.而且,Swift中的数组不必是对象类型. OC中的NSAr ...

  3. java泛型中<?>和<T>区别

    public static void printColl(ArrayList<?> al){                Iterator<?> it = al.iterat ...

  4. [转]java List和数组相互转换方法

    原文地址:https://blog.csdn.net/zjx2016/article/details/78273192 前言在java项目中数组和list集合(这里指ArrayList)经常需要互相转 ...

  5. IT兄弟连 Java语法教程 数组 数组的初始化

    Java语言中数组必须先初始化,然后才可以使用.所谓初始化,就是为数组的数组元素分配内存空间,并为每个数组元素赋初始值. 这时有人会问,能不能只分配内存空间,不赋初始值呢?答案是肯定不行的,一旦为数组 ...

  6. c语言中数组的定义和java中数组定义的一些区别

    感谢原文:https://blog.csdn.net/gzwdz778/article/details/79799408 一维情况下: c中,数组的声明需要给出数组的维数,比如: int arr[5] ...

  7. Java基础从数组到集合之间关键字的区别!!!!

    1.&& 和 &区别和联系: 相同点 : 结果是一样的.       不同点 :如果使用双&号判断,如果说条件一为false,不会判断条件二,但是单&号会继续判 ...

  8. Java NIO中核心组成和IO区别

    1.Java NIO核心组件 Java NIO中有很多类和组件,包括Channel,Buffer 和 Selector 构成了核心的API.其它组件如Pipe和FileLock是与三个核心组件共同使用 ...

  9. Java中equal和==区别及String创建过程

    Java中equal和==区别 1.起因 在一段Java代码中,使用了两种实现方式. //第一种命令行输入 int main (String[] args) { if(args[0] == " ...

随机推荐

  1. url参数的编码解码Demo

    为了保证在页面传递数据的安全性,我们通常会对Url传递的参数进行编码解码操作.我们写一个Demo剖析URL编码解码过程. 完整Demo下载地址 1. Url参数如何在服务端进行编码和解码. 1.1 U ...

  2. HDU4416Good Article Good sentence(后缀自动机)

    Problem Description In middle school, teachers used to encourage us to pick up pretty sentences so t ...

  3. Win8 安装.Net Framework3.5(2.0,3.0)组件二种方式

    第一种: 通过命令+win8映像文件 找到系统盘cmd文件:C:\WINDOWS\system32\Cmd.exe 右键“以管理员身份运行”,然后弹出一个黑框框. 黑框框里面输入一下命令: dism. ...

  4. HDOJ1016(标准dfs)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  5. 关于64位操作系统使用C#访问注册表失败的问题

    通过C#的注册表类 Registry.GetValue 进行访问时,其返回值一直为空.然后认真检查检查再检查了注册表路径,发现路径没有一点问题,不说废话,上代码: if (Registry.GetVa ...

  6. Task Crontab

    Crontab 1.查看任务 crontab -l 2.编辑任务 1)对应用户登录后编辑其下的作业 crontab -e 2)删除指定用户任务 crontab -u user -r 3)删除用户下指定 ...

  7. C Primer Plus学习笔记(六)- C 控制语句:分支和跳转

    if 语句: if 语句被称为分支语句(branching statement)或选择语句(selection statement) if 语句的通用形式: if (expression) state ...

  8. Linux 命令及获取帮助 目录文件浏览,管理和维护

    开启Linux操作系统,要求以root用户登录GNOME图形界面,语言支持选择为汉语 使用快捷键切换到虚拟终端2,使用普通用户身份登录,查看系统提示符 $ 使用命令退出虚拟终端2上登录的用户 exit ...

  9. Solaris ssh配置主机间信任关系

    假设需要配置从主机com00biiitf001登录主机ols00biiitf001时不需要密码,则采用以下步骤配置: com00biiitf001上产生公用/私有密钥对 $ ssh-keygen -t ...

  10. js笔试题一套(未完待续)

    1.下面程序的运行结果是: function test(x, y, z) { alert(test.length); alert(arguments.length); alert(arguments. ...