java学习之数组(一)【内存】
在java语言当中,为了更方便多个数据的管理,这里提供数组。
比如说,现在我们有一组数据,7,8,9,9,为了保存这四个数据,我们分别要定义变量来保存,少了还好说。但是假如,有100多个数据呢,我们一个一个定义起来,岂不是很麻烦。这个时候我们就引入了数组这个概念,来方便我们对多个数组的管理。
数组的定义:同一种类型数据的集合,通俗来讲,数组就是一个容器,容纳同类型的数据。
数组的书写格式:元素类型[] 数组名 = new 元素类型[元素的个数或者叫做数组的格式]。
class ArrDemo{ public static void main(String[] args) {
/**
*数组的定义格式:元素类型[] = new 元素类型[数组的长度或者叫做元素的个数];
*我们知道数组是存放许多同类型的元素的实体,之所以叫做实体是因为他是实实在在存放数据的地方。那么我们为了能区别于其他的变量声明,这里我们
*用一个关键字来创建他,这个关键字就是new。那么之后的int[]是表示建立一个int类型的数组,其中的数字7就是这个数组的长度
*数组的一个特点就是,一旦你定义了一个数组,你就必须明确他的长度。
*/ int[] arr = new int[7]; /**
*在定义完数组之后,我们就开始访问他,这个时候数组提供给我们的就是一个索引,表示我们要去的数据的位置。
*数组的索引的特点就是都是从0开始的,并且在你没有初始值的时候,他们都有各自类型的默认值。
*
*byte,short,int类型的默认值是0
*float类型的默认值是0.0f
*double类型的默认值是0.0
*char类型的默认值比较特殊,他的默认类型是'\u0000';这里可能有一个疑问,char当中不是只能容纳一个字符么,为什么这里可以容纳五个。因为这里容纳的
*并不是字符,而是字符的unicode编码,以\u 开头的就是unicode编码,表示的意思是空字符。
*
*/ System.out.println(arr[0]);//这里打印出来的就是int类型的默认值0; } }
这里我们也可以通过索引对数组中元素进行赋值,比如;arr[0] = 89;这样就把索引为0位置的数字,改为了89这个整数。
为了更好的理解数组,我们来看一下数组在内存当中的表现。
当我们运行一个程序的时候,我们需要在内存当中单独开辟一个内存空间,同时这个被分配的内存又有一个进一步的更细致的内存划分。因为这个内存划分就跟一个操场的划分差不多,有足球场,篮球场,田径区等等,这样划分的目的是为了让各个区域独立开,更高效的利用内存。如果一个操场,什么都有,一个是太乱不容易管理,一个是不安全容易出事。那么内存到底划分为哪些部分呢?
内存的划分:
1、寄存器,这个我们用不着,这个都是cpu直接操作的。
2、本地方法区。//这个是跟所处的系统相关的,因操作系统不一样
3、方法去。//内加载机制
4、栈存储区。
5、堆存储区域。
栈内存:
里边存储的是什么?
存储的都是局部变量。所谓的局部变量就是凡是定义在方法当中的变量都是局部变量。在类当中直接存储的就不是局部变量。
该局部变量所属的作用域一旦结束,那么这个局部变量也随之被内存自动释放。
特点:栈内存更新速度很块,声明周期很短。
class MemDemo{ int a = 20;//这个没有定义在方法当中,这个就不是局部变量
{
int c = 8777;//在局部代码块当中定义的变量也是局部变量,限定局部变量的声明周期。当我们使用一大部分变量的时候,有些变量用完之后,就释放了,这部分可以利用这种结构。
}
public static void main(String[] args) { int b = 89;//这个就是定义在方法当中的,所以他是局部变量
//byte[] bt = new byte[9];
//short[] sr= new short[9];
//System.out.println(bt[0]);
//System.out.println(sr[0]);
for(int x=5;x<9;x++)//这里面的x也是局部变量
} }
堆内存:
堆内存存储的是什么呢?
堆内存当中存储的是数组和对象(其实数组就是对象的意思)。凡是new关键字建立的都在堆当中。数组和对象都是实体,实体的就是实实在在存储的个数。实体用于封装数据,而且都封装数字。实体当中存储这个一堆数据,其中一个数据消亡了,那么其他的数据都还可以用的。那么此时这个实体肯定是不能随时释放的。
堆不会随时释放,
特点:
1、每一个实体都有一个唯一的地址值。
2.堆内存中的每一个变量都有默认初始化的值,根据的类型的不同而不同。
3、垃圾回收机制。
方法先进栈,然后变量才进栈。当我们把数组实体赋值给一个栈内的变量的时候,其实就是在堆内存开辟了一个内存空间,并且给她分配了一个内存地址,此时地址虽然是二进制,但是为了表示方便采用大进制的来存储,即十六进制。这个时候数组就有一个唯一的地址。在我们定义数组的时候,我们定义了元素的个数,那么数组实体当中就为这些个元素分配了一个唯一的索引。当我们在堆内存当中定义一个数组实体之后,他会进行一次默认的初始化。这个就是一个规定。堆内存的变量有个特点,就会有一个默认初始化。
那么当把堆内存当中的实体付给栈内存当中的变量时,实际上是把堆内存当中的变量地址,赋值给栈内存的变量。栈内存当中的变量通过操作堆内存的地址,来操作数据。这个种方式就叫做引用。
当我们给数组赋值的时候,一定要考虑到类型是否相同。
class MemDemo{ public static void main(String[] args) { int[] a = new int[9];
a[0] = 's';//非法的数据类型不一样
a[0] = null;//非法的数据类型不一样
a = null;//null 的一个作用在与 解索引,即栈内存当中变量与堆内存当中的变量分开。 } }
当堆内存当中没有被栈内存当中的变量引用时,此时就变成了垃圾。会被GC不定时回收掉,以免内存占满,系统崩溃掉。
内存图:
数组操作的时候,出现的小错误:
1、不能超出索引范围。
class MemDemo{ public static void main(String[] args) { int[] a = new int[3]; System.out.println(a[3]); } }
此时我们编译的时候,没有报错,但是我们明明知道他是错误的。我们编译的时候,并没有分配内存。 比如说假如我们编译完了就分配内存了,那么如果我们编译完了放在那里,并没有运行,此时如果分配的话,显示不合理,也不合逻辑。
编译的过程是检查是否有语法的错误,但是在这里我们的语法并没有错误。因为a[3]的这个索引只有程序运行的时候,才会去找。此时我们再用JVM来运行,此时它创建完数组之后,来找这个内存的时候发现并没有找到,所以报错:连位置都详细告诉我们了。
假如我们这样:
class MemDemo{ public static void main(String[] args) { int[] a = new int[3]; a = null; System.out.println(a[0]); } }
当引用型变量即数组或者对象,在没有任何实体指向的情况下被调用,还在用他操作实体,此时就会报空指针错误。
如果我们直接打印数组,会出现什么呢?
class MemDemo{ public static void main(String[] args) { int[] a = new int[3]; //a = null; System.out.println(a); } }
运行结果:
这个字符什么意思呢?
我们分开看:
1、"["这个符号代表是数组。
2、"I"这个代表是int类型
3、@分界线,左边是需要看懂的。
4、15bdc50这个是数组实体的哈希值,是一个算法(如果冲突就继续往下算,这个哈希算法是采用windows的,根据系统自己定义的),用这个算法计算,数组实体在内存当中的存储位置。
未完待续。
java学习之数组(一)【内存】的更多相关文章
- Java细节整理——数组与内存控制
重点:使用Java数组之前,必须对数组对象进行初始化. 当数组的所有元素都被分配了合适的内存空间,并指定了初始值时,数组的初始化完成.程序以后将不能重新改变数组对象在内存中的位置和大小. 知识点整理: ...
- java 基础概念 -- 数组与内存控制
问题1: Java在声明数组的过程中,是怎样分配内存的? 在栈内存中 建一个数组变量,再在堆内存中 建一个 数组对象.至于详细的内存分配细节,还得看 该初始化是 数组动态初始化 还是 数组静态初始化. ...
- Java学习之数组的简单用法
•概念 其实所谓的数组指的就是一组相关类型的变量集合,并且这些变量可以按照统一的方式进行操作. 数组本身属于引用数据类型,那么既然是引用数据类型,这里面实际又会牵扯到内存分配: 而数组的定义语法有两种 ...
- JAVA学习笔记--数组初始化
JAVA中,数组只是相同类型的.用一个标识符名称封装到一起的一个对象序列或基本类型数据序列.数组通过方括号下标操作符[]来定义和使用,要定义一个数组只需在类型名后面加上一个方括号即可,如: int[] ...
- 透过字节码分析java基本类型数组的内存分配方式。
我们知道java中new方式创建的对象都是在堆中创建的,而局部变量对应的值存放在栈上.那么java中的int [] arr={1,2,3}是存放在什么地方的呢,int []arr = new int[ ...
- Java学习之==>数组【array】
一.定义数组 /** * 一维数组定义 * * 为数组插入元素 */ public void case1() { // 声明 int[] arr1; // 声明+初始化 int[] arr2 = ne ...
- java学习之数组(二)
在上一节中我们讲到了数组的概念,定义,以及在内存当中的表现形式.那么这里我们来说一下,数组的另一种定义方式. 在上一篇当中我们规定是这个样子定义数组的, class ArrDemo { public ...
- java学习笔记 --- 数组
一.Java的内存分配 A:栈内存: 存储局部变量,只要是在方法中定义的变量都是局部变量.一旦变量的生命周期结束该变量就被释放. B:堆内存: 存储所有new出来的,及实体(对象),每一个实体 ...
- Java学习:数组的使用和注意事项
数组 数组的概念:是一种容器,可以同时存放多个数据值 数组的特点: 数组是一种引用数据类型 数组当中的多个数据,类型必须统一 数组的长度在程序运行期间不可以改变 数组的初始化:在内存当中创建一个数组, ...
随机推荐
- 轻量级的原型设计工具-Axure RP
1. 软件下载地址: http://www.downxia.com/downinfo/25742.html 这个版本不需要注册码,不需要安装,存绿色版. 2. 基本介绍教程: http://wenku ...
- 关于在MDK4.5以上版本不能使用JLINK V8的解决办法
如果安装MDK4.50版本以上不能使用jlink8的话,请安装jlink 4.36k版本(或以下)驱动,安装完成后,把\SEGGER\JLinkARM_V436k目录下的JLinkARM.dll拷贝到 ...
- Axiom3D学习日记 0.Axiom基础知识
Axiom 3D Engine An open-source, cross-platform, managed 3D rendering engine for DirectX, XNA and Ope ...
- DataTable和List集合互转
/// <summary> /// 将集合转换成DataTable /// </summary> /// <param name="list"> ...
- Android开发--去掉标题栏
Android开发中为了尽可能美观,会去掉标题栏.去掉标题栏有三种方法. 一.在Activity代码里实现 在代码中实现以下方法: this.requestWindowFeature(Window.F ...
- [转]mysql导出导入中文表解决方法
在开发过程中会经常用到mysql导出导入中文表,本文将详细介绍其如何使用,需要的朋友可以参考下. 在开发过程中会经常用到mysql导出导入中文表,本文将详细介绍其如何使用,需要的朋友可以参考下一.先针 ...
- sqlserver-事务处理
事务的概念:简单说就访问并可能更新数据库中各种数据项的一个程序执行单元,一旦开启事务,所有对数据的操作要么全部执行,要么全部都不执行.单条sql语句本身就是一个事务. 事务的属性: 事务是作为单个逻辑 ...
- Vijos1386 IOI2007 矿工配餐 动态规划
感觉早些年IOI的题都不难啊,也就NOIp难度……现在貌似变难了 状态用dp[n][a1][b1][a2][b2]表示 n表示处理到前n个餐车 第一组矿工得到的最近一种食物用a1表示,a1的上一种食物 ...
- mac 下maven的安装
最近在学习mahout,这些安装相关软件的步骤先记下来,避免以后忘记. 1.首先在mac上查看本机的java版本,如果没有需要自己去安装: 我的电脑上安装的java是1.7.0_79 2.在http: ...
- 【BZOJ3295】【块状链表+树状数组】动态逆序对
Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计 ...