Java 基础【04】数组内存分配

简介:

       可能Java 数组大家都很熟悉,最近我遇到了一个关于Java 数组内存分配的问题。

        突然发现许多书上“基本数据类型存储在栈内存当中,对象则保存在堆内存”这句话完全是错误的。下面是个简单的例子代码:

复制代码
public class Test {
    public static void main(String[] argv) {
        // 静态初始化数组
        String[] names = { "Michael", "Orson", "Andrew" };
        // 动态初始化数组
        String[] animal = new String[4];
        // 让animal 指向 namens 数组所引用的数组
        names = animal;
        
        System.out.println(names.length);
        System.out.println(animal.length);
    }
}
复制代码

    “Java 数组大小是不能改变的”这可能大家都听过,那上面这段代码就有问题了。

    animal [] 长度为4,而names [] 数组的长度只有3,但是经过一个赋值语句,两个数组的大小就都变为4了。

    这不是改变了数组的大小吗?

    好吧,问问技术前辈吧,对数组的存储方式有了全新的认识。

    下面是我的一点理解:(如果有错误的,刚好被大神你看到了,也请你能够指出来。)

    上面的的 names 和 animal 不代表这个数组对象,仅仅是数组的变量而已,和C里面的指针是一样的,这样的变量叫做引用变量。

    数组对象是保存在堆内存当中,大小当然是不能改变的,但是数组变量却能够指向其他的数组对象,可以看看下面这个图:

      

    蓝虚线是赋值语句 names = animal; 之前 names 和 animal 数组变量指向的堆内存当中数组对象;

    红线是是赋值语句 names = animal;之后 names 和 animal 数组变量都同时指向一个数组对象。当然这时候 Java 垃圾回收机制这时候就会发现那个没人引用的数组对象然后把它带走。

    从上面还可以看到,“Michael”,"Orson","Andrew" 这些都是基本的数据类型吧。但是他们却存储在堆内存当中。  

    实际上应该这样说:局部变量放在栈内存当中,(像上面的 names[],animal[] 这种引用类型的变量,还有一些基本类型的变量),但应用变量所引用的对象是保存是堆内存当中的。(包括数组还有一些我们平常写的普通的类对象)

    Java在堆内存当中的对象通常是不允许直接访问的,但你可以想到直接访问的后果。为了访问堆内存当中的对象,这时候就需要引用变量这个中介。

    什么时候Java存储在栈内存中的变量是仅仅是引用变量? 什么时候它又换了身份变为货真价实的JAVA对象纳?嗯,看看下面这个例子:

复制代码
    public class Animal {
        private String name;
        private int age;

        Animal(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public void info() {
            System.out.println(name + " " + age);
        }
    }
public class Test {

    public static void main(String[] argv) {
        // 动态初始化数组
        Animal[] animal = new Animal[2];
        Animal cat = new Animal("cat", 1);
        Animal dog = new Animal("dog", 2);
        animal[0] = dog;
        animal[1] = cat;

        // 当数组变量引用对象的方法(或者属性)的时候,它就变为实际的Java 对象
        System.out.println(animal.length);
        //dog 这个原本存储在栈内存当中的对象引用通过调用对象的方法变为实际的对象
        dog.info();
        animal[0].info();
    } 
}
复制代码

     只有当栈内存中的引用变量调用了对象的方法或者是指向了对象的属性的时候,它就从变量真正成了对象了。

   (比如上面例子中的 cat,dog 对象引用变量,animal[]数组变量)。 通过  

    animal[0] = dog;

    animal[1] = cat;

    使得两个变量都指向了存储在堆内存当中的对象,所以他们俩个打印出来的信息是一模一样的。

 



    上图中蓝线是赋值语句:

    animal[0] = dog; animal[1] = cat;

    之前的变量指向的状态,红虚线是赋值语句之后的状态,animal[0]和dog ,animal[1] 和cat 所指向的都是相同的堆内存空间。


 本文转自Orson博客园博客,原文链接:http://www.cnblogs.com/java-class/archive/2013/05/16/3082304.html,如需转载请自行联系原作者
相关文章
|
15天前
|
监控 算法 Java
Java中的内存管理:理解Garbage Collection机制
本文将深入探讨Java编程语言中的内存管理,特别是垃圾回收(Garbage Collection, GC)机制。我们将从基础概念开始,逐步解析垃圾回收的工作原理、不同类型的垃圾回收器以及它们在实际项目中的应用。通过实际案例,读者将能更好地理解Java应用的性能调优技巧及最佳实践。
55 0
|
9天前
|
存储 缓存 Java
java线程内存模型底层实现原理
java线程内存模型底层实现原理
java线程内存模型底层实现原理
|
2天前
|
存储 安全 Java
Java数组(Arrays)详解
Java 中的数组是一种用于存储固定数量同类型数据的高效数据结构,支持连续内存存储和随机访问。数组可以声明并初始化,通过索引访问和修改元素,获取长度,使用循环遍历,支持多维形式,并可通过 `Arrays` 类的方法进行复制和排序。数组具有固定大小和类型安全的特点,但需注意越界等问题。灵活运用数组能显著提升编程效率。
|
5天前
|
存储 算法 Java
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
本文介绍了 JVM 的内存区域划分、类加载过程及垃圾回收机制。内存区域包括程序计数器、堆、栈和元数据区,每个区域存储不同类型的数据。类加载过程涉及加载、验证、准备、解析和初始化五个步骤。垃圾回收机制主要在堆内存进行,通过可达性分析识别垃圾对象,并采用标记-清除、复制和标记-整理等算法进行回收。此外,还介绍了 CMS 和 G1 等垃圾回收器的特点。
14 0
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
|
12天前
|
Java 编译器
深入理解Java内存模型:从基础到高级
本文旨在通过通俗易懂的方式,引导读者深入理解Java内存模型(JMM)的核心概念和工作原理。我们将从简单的基础知识入手,逐步探讨重排序、顺序一致性问题以及volatile关键字的实现机制等高级主题。希望通过这篇文章,你能够对Java内存模型有一个清晰、全面的认识,并在实际编程中有效地避免并发问题。
|
9天前
|
存储 算法 Java
深入理解Java内存管理
本文将通过通俗易懂的语言,详细解析Java的内存管理机制。从JVM的内存结构入手,探讨堆、栈、方法区等区域的具体作用和原理。进一步分析垃圾回收机制及其调优方法,最后讨论内存泄漏的常见场景及防范措施。希望通过这篇文章,帮助读者更好地理解和优化Java应用的内存使用。
|
15天前
|
存储 Java 数据处理
Java 数组的高级用法
在 Java 中,数组不仅可以存储同类型的数据,还支持多种高级用法,如多维数组(常用于矩阵)、动态创建数组、克隆数组、使用 `java.util.Arrays` 进行排序和搜索、与集合相互转换、增强 for 循环遍历、匿名数组传递以及利用 `Arrays.equals()` 比较数组内容。这些技巧能提升代码的灵活性和可读性,适用于更复杂的数据处理场景。
|
14天前
|
监控 算法 Java
Java中的内存管理与垃圾回收机制
本文将深入探讨Java编程语言中的内存管理方式,特别是垃圾回收(Garbage Collection, GC)机制。我们将了解Java虚拟机(JVM)如何自动管理内存,包括对象创建、内存分配以及不使用对象的回收过程。同时,我们还将讨论不同的垃圾回收算法及其在不同场景下的应用。
|
12天前
|
监控 算法 Java
深入理解Java中的垃圾回收机制在Java编程中,垃圾回收(Garbage Collection, GC)是一个核心概念,它自动管理内存,帮助开发者避免内存泄漏和溢出问题。本文将探讨Java中的垃圾回收机制,包括其基本原理、不同类型的垃圾收集器以及如何调优垃圾回收性能。通过深入浅出的方式,让读者对Java的垃圾回收有一个全面的认识。
本文详细介绍了Java中的垃圾回收机制,从基本原理到不同类型垃圾收集器的工作原理,再到实际调优策略。通过通俗易懂的语言和条理清晰的解释,帮助读者更好地理解和应用Java的垃圾回收技术,从而编写出更高效、稳定的Java应用程序。
|
16天前
|
存储 Java
java的Excel导出,数组与业务字典匹配并去掉最后一个逗号
java的Excel导出,数组与业务字典匹配并去掉最后一个逗号
34 2
下一篇
无影云桌面