まず、メモリアレイ
配列参照変数は参考であり、基準変数が有効なメモリアレイ要素に基準点が配列変数を介してアクセスすることができる場合にのみ、有効な任意のメモリを指すことができます。
実際のオブジェクトは、スタックアレイ(ヒープ)メモリに格納されている、配列オブジェクト参照変数の配列参照はローカル変数である場合、それは、スタック(スタック)メモリに格納されます。メモリに格納された配列の模式図。
ヒープメモリのようにあなたがアクセス配列要素に必要がある場合、プログラムは唯一のp [インデックス]の形で実現することができます。その配列参照変数は、スタックメモリアレイ要素にアクセスするための基本的な方法です。
ヒープメモリとスタックメモリ:
ヒープ(ヒープ)メモリ:Java仮想マシンが起動パーマネント、大きなメモリ領域の割り当て。唯一のヒープメモリ。
スタック(スタック)メモリ:各ランタイム法の一時的な、小さなメモリ領域を割り当てます。各方法は、スタック領域のためのプロセスの終了は、破壊される場合、それ自身のスタック領域を有しています。
メソッドの実行は、各メソッドが独自のメモリ・スタックを確立するときに、変数がメソッドの実装の端部と、スタックメモリにいずれかによって、このメソッド内でいずれかであろう定義、この方法は、メモリ・スタックを破壊します。従って、この方法で定義されたすべてのローカル変数は、スタックメモリであり、アプリケーションオブジェクトを作成するときに、オブジェクトが(ラージ・オブジェクトを作成するコストため)を繰り返し使用するためのデータ領域ランタイムに記憶されますこのランタイムデータ領域はヒープメモリです。ヒープメモリオブジェクトは、オブジェクトがまだ破壊されない、方法も終了後、オブジェクトが参照される他の追加の変数(パラメータ渡す方法では非常に一般的)を参照することができ、方法の終わりで消滅しません。オブジェクトが変数の参照もされていない場合にのみ、システムのガベージコレクタは、適切なタイミングでそれを再利用します。
配列のヒープメモリは、自分自身を指しているすべての参照変数がない場合、配列はゴミになり、アレイはガベージコレクタのメモリ回収システムによって占有されます。したがって、ガベージコレクタは、アレイによって占有されるメモリ空間を再利用することを可能にするために、アレイを割り当てることができるうんちがヌルである、それは配列参照変数と実際の配列との間の関係を挙げ切断、実際のアレイは、ごみとなるであろう。
長いタイプに互換性がある限り、それは、可変長の配列の錯覚を作成することになる別の配列への実際の配列変数ポイントを作ることができます。
1 クラスArrayTestの 2 { 3 パブリック 静的 ボイドメイン(文字列[]引数) 。4 { 5つの // 配列に定義された静的メソッド 。6 INT [] = A {1,3,5 }; 7 // 動的初期定義アレイ 8 のvar B = 新しい新しい INT [4。;] 9。 10 のSystem.out.println( "配列Bの長さ:" + てb.lengthに); 11。 // 出力配列Aのサイクル、B 12である ため(INT :I) 13は、 { 14 システム。 out.print( "" +I); 15 } 16 System.out.print( "\ N-"の) 。17 用(INT I <てb.lengthに; I = 0 I ++ ) 18である { 19 System.out.printの( "" + B [I] ); 20は、 IF(私は== -てb.length 1。 ) 21が System.out.print( "\ N-"の); 22である } 23は // なぜなら、bはINT []参照型は、点bを行うことが可能です参照配列は、点 24 = Bを、 25 のSystem.out.println(「参照変数ポイント配列の長さの点Bに、点Aの配列に」+ てb.lengthに); 26である } 27 } 28 ----------実行するJava(キャプチャー画面)---------- 29、配列Bの長さ:4 30 。1. 3. 5 31が 0 0 0 0 32点の点列に配列変数bの長さの基準点の後:3 33は 34である(0秒を処理し)、出力完了-正常終了
変数Bの変数は、ガベージコレクタを待って、ごみに最初の配列、失われた参照元の配列要素ヒープメモリ内のこの時間を、参照された後、それを再利用します。
第二に、配列の初期化の基本的なタイプ
アレイの基本的なタイプのために、値を直接配列要素の配列要素に格納され、配列を初期化するとき、したがって、直接対応する配列要素に配列、および配列要素のためのメモリ領域を割り当てます。
クラスPrimitiveArrayTest { 公共 静的 ボイドメイン(文字列[]引数) { // 型int []配列変数の定義 のint []配列; // 動的初期化配列、配列長5 アレイ= 新しい新しい INT [5 ]; // 周期的に各アレイ素子の割り当て のための(I 0 = VAR;私は<Array.lengthとすること; I ++ ) { アレイ[I] = I + 10 ; } // 出力アレイのサイクル のために(INT I:配列) { システム。 out.printlnを(I); } } } ----------のJava(キャプチャー画面)----------実行 10 11 12である 13は 14 (とる出力が完了した 1秒) -正常終了
実行はint []配列、スタックメモリ割り当ておよびヒープメモリ(Java仮想マシンの起動がある)、ヌル参照を定義し、この時間は、基準変数は、任意の有効なメモリにポイントをしない、それは配列を知ることができません長さ
配列=新しいINT [5]、動的な初期化は、システムが割り当てられ、割り当てられたメモリ記憶空間のアレイのための初期値をデフォルト設定されます:0は、すべての配列要素に割り当てられています。
用(varがI = 0、Iは<Array.lengthとすること; I ++ )
{
配列[I] = I + 10 ;
}
サイクル配列代入
第三に、初期の参照型
割り当ての基本的なタイプ:ダイレクト変数メモリに格納された値。
割当ての参照型:変数に格納された参照されたオブジェクトのメモリセルの数(先頭アドレス)。
配列の配列要素のタイプを参照するときに引用されたので、状況はより複雑です。各配列要素は、メモリの別の部分を指し、このメモリは、有効なデータを格納することを参照して格納されています。
Personクラスの定義
1 class Person 2 { 3 public int age; 4 public double height; 5 //定义一个方法 6 public void info() 7 { 8 System.out.println("年龄:"+age+",身高:"+height); 9 } 10 }
下面程序定义一个Person[]数组,接着初始化这个Person[]数组,并为这个数组的每个元素指定值。
1 public class ReferenceArrayTest 2 { 3 public static void mian(Srting[] args) 4 { 5 //定义一个sudentd数组,类型Person[] 6 Person[] students; 7 //执行初始化 8 students=new Person[2]; 9 10 //创建两个Person实例 11 var zhang=new Person(); 12 zhang.age=15; 13 zhang.height=158; 14 15 var lee=new Person(); 16 lee.age=16; 17 lee.height=168; 18 19 students[0]=zhang; 20 students[1]=lee; 21 22 //下面代码的执行结果完全一样 23 lee.info(); 24 students[0].info(); 25 } 26 }
执行Person[] students;代码时,这行代码仅仅在栈内存中定义了一个引用变量,也就是一个指针,这个指针并未指向任何有效内存区。
执行动态初始化,默认由系统指定初始值null。
students=new Person[2];
然后代码定义了zhang和lee两个Person实例,实际上分配了四个内存,在栈内存储zhang和lee两个引用变量,还在堆内存储两个Person实例,如下所示:
students[0]=zhang;
students[1]=lee;
从图可以看出zhang和students[0]同时指向一个内存区,且都为引用变量,因此通过zhang和students[0]来访问Person实例的方法和变量效果是一样的,无论修改students[0]指向的实例还是zhang指向的实例,所修改的其实是一个内存区。
四、没有多维数组
java语言的数组类型还是引用类型,这个引用指向真实的数组内存。数组元素的类型也可以是引用,如果数组元素的引用再次指向真实的数组内存,这种情况看上去就很像多维数组。
定义一个变量的用法:type varName,type是变量类型。如果定义一个引用变量的数组类型,只需要将这个type具体成int[]。
二维数组的定义:
type[][] arrayName;
从采用上面的语法格式来定义二维数组,但它的实质还是一维数组,只是数组元素还是引用,数组元素里保存的引用指向一位数组。
对二维数组的初始化,同样可以将数组看成以为数组初始化,把这个“二维数组”当成一一维数组,其元素类型是type[]类型,可以采用以下语法进行初始化
arrayName=new type[length][]
上面的语法相当于初始化一个一维数组,这个一维数组的长度为length,同样这个一维数组的数组元素是引用类型(数组类型),所以系统为每个元素分配的初始值为null。这个二维数组完全可以当成一维数组:使用new type[length]相当于定义了length个type类型变量;类似的,使用new type[length][]初始化这个数组后,相当于定义了length个type[]类型的变量,当然这个type[]类型的变量都是数组类型,因此需要再一次进行初始化。
1 class 二维数组 2 { 3 public static void main(String[] args) 4 { 5 //定义一个二维数组 6 int[][] a; 7 //把a当成一维数组进行初始化,初始化a为一个长度为4的数组 8 //a数组的数组元素有是引用类型 9 a=new int[4][]; 10 //把a当成一维数组,遍历a数组的每个元素 11 for(int i=0;i<a.length;i++) 12 { 13 System.out.println(a[i]); 14 } 15 //初始化a数组的第一个元素 16 a[0]=new int[2]; 17 a[0][0]=1; 18 a[0][1]=2; 19 20 //遍历二维数组a的第一个元素 21 for(int i=0;i<a[0].length;i++) 22 { 23 System.out.println(a[0][i]); 24 } 25 } 26 }
[][] a;这一行代码,将在栈里定义一个引用变量,这个变量并未指向任何有效的内存空间,此时堆内存还未为这行代码分配任何存储区。
a=new int[4][];程序对数组进行初始化,这行代码让a变量指向一块长度为4的内存空间,这个长度为4的数组里每个数组元素都是引用类型(数组类型),系统为这些数组元素分配初始值:null。此时数组a在内存中存储的示意图:
a[0]=new int[2];
a[0][0]=1;
a[0][1]=2;
对一个数组原素a[0]进行初始化
初始化多维数组时,可以只指定左边维的大小;当然也可以一次指定每一维的大小。
1 int[][] b=new int[3[4];
上面的代码定义一个b数组变量,这个变量指向一个长度为3的数组,这个数组的每个元素又是一个数组类型,他们各自指向长度为4的int[]数组,每个数组的元素为0。示意图为:
还可以使用静态初始化方式来初始化二维数组,使用静态初始化方式来初始化二维数组,二维数组的每个数组元素都是一维数组,因此必须指定多个一维数组作为二维数组的初始值。代码如下:
//使用静态初始化方法来初始化一个二维数组 String[][] str1=new String[][]{new String[3],new String[]{"hello"}}
结论:二维数组是一维数组,其数组元素是一维数组;三维数组其数组元素是二维数组。