Java 改善の章 (18)-----配列 1: JAVA 配列を理解する

黄舟
リリース: 2017-02-10 11:48:52
オリジナル
1327 人が閲覧しました

ああ、川は牛おじさんが言ったほど浅くもなく、小さなリスが言ったほど深くもありません。自分で試してみなければわかりません。伝聞は常に現象を示すことしかできません。自分で試してみることによってのみ、その深さを知ることができます。 ! ! ! !

1. 配列

配列とは何ですか?配列とは何ですか?私の考えでは、配列は次のようにあるべきです。 new キーワードを使用して配列を作成およびアセンブルし、整数のインデックス値を使用して要素にアクセスし、そのサイズは不変です。

しかし、これは配列の最も表面的なものにすぎません。もっと深く?つまり、配列は単純な複合データ型であり、配列内の各データは同じデータ型を持ち、範囲を超えない添字値を一意に使用します。配列内の要素。もっと深いものがあります。つまり、配列は特別なオブジェクトです。 ! (私はこの LZ をよく理解していませんし、JVM を読んだことがないので、私の洞察は限られています)。次の参照: http://www.php.cn/、http://www.php.cn/

配列が他の言語でどのようなものであっても、Java ではオブジェクトです。かなり特殊なオブジェクト。

public class Test {
    public static void main(String[] args) {
        int[] array = new int[10];
        System.out.println("array的父类是:" + array.getClass().getSuperclass());
        System.out.println("array的类名是:" + array.getClass().getName());
    }
}
-------Output:
array的父类是:class java.lang.Object
array的类名是:[I
ログイン後にコピー

上の例から分かるように、配列は Object の直接のサブクラスです。これは「オブジェクトの最初のタイプ」に属しますが、通常の Java オブジェクトとは大きく異なります。クラス名からもわかるように、「これは何ですか?」 ? JDK にはこのクラスが見つかりませんでした。この「[I」は正当な識別子ではないと言われています。カテゴリとして定義するにはどうすればよいでしょうか?したがって、SUM の天才たちは配列の最下層に特別な処理を行ったに違いないと思います。

次の例を見てみましょう:

public class Test {
    public static void main(String[] args) {
        int[] array_00 = new int[10];
        System.out.println("一维数组:" + array_00.getClass().getName());
        int[][] array_01 = new int[10][10];
        System.out.println("二维数组:" + array_01.getClass().getName());
        
        int[][][] array_02 = new int[10][10][10];
        System.out.println("三维数组:" + array_02.getClass().getName());
    }
}
-----------------Output:
一维数组:[I
二维数组:[[I
三维数组:[[[I
ログイン後にコピー

この例を通して、[ は配列の次元を表し、1 つの [ は 1 次元を表し、2 [ は 2 次元を表します。配列のクラス名は、いくつかの '[' と配列要素型の内部名で構成されていると簡単に言えます。よくわからない場合は、見てみましょう:

public class Test {
    public static void main(String[] args) {
        System.out.println("Object[]:" + Object[].class);
        System.out.println("Object[][]:" + Object[][].class);
        System.err.println("Object[][][]:" + Object[][][].class);
        System.out.println("Object:" + Object.class);
    }
}
---------Output:
Object[]:class [Ljava.lang.Object;
Object[][]:class [[Ljava.lang.Object;
Object[][][]:class [[[Ljava.lang.Object;
Object:class java.lang.Object
ログイン後にコピー

この例から、配列の「本当の顔」を見ることができます。同時に、配列が通常の Java クラスとは異なることもわかります。通常の Java クラスは完全修飾パス名とクラス名を唯一の識別子として使用しますが、配列はいくつかの [+L+配列要素クラスの完全名を定義します。一意に識別するためのパス + クラス。この違いは、配列と通常の Java クラスの実装に大きな違いがあることをある程度説明できるかもしれません。おそらく、この違いは、JVM が配列と通常の Java クラスを処理するときに区別するために使用できるかもしれません。

これが何であるか、誰がそれを宣言するか、そしてどのように宣言されるかは脇に置いておきましょう (これらは今はわかりません! しかし、1 つ確認できることは、これは実行時に決定されるということです)。まず以下を見てください:

public class Test {
    public static void main(String[] args) {
        int[] array = new int[10];
        Class clazz = array.getClass();   
        System.out.println(clazz.getDeclaredFields().length);   
        System.out.println(clazz.getDeclaredMethods().length);   
        System.out.println(clazz.getDeclaredConstructors().length);   
        System.out.println(clazz.getDeclaredAnnotations().length);   
        System.out.println(clazz.getDeclaredClasses().length);   
    }
}
----------------Output:
0
0
0
0
0
ログイン後にコピー

この実行結果から、親愛なる [I にはメンバー変数、メンバー メソッド、コンストラクター、アノテーション、さらには length メンバー変数さえも含まれていないことがわかります。完全に空のクラスです。長さが宣言されていないのに、array.length を実行するときにコンパイラがエラーを報告しないのはなぜですか?実際、配列の長さは非常に特殊なメンバー変数です。配列が Object の直接クラスであることはわかっていますが、Object にはメンバー変数 length がないため、length が配列のメンバー変数である必要がありますが、上記の例から、配列にはメンバー変数がないことがわかります。まったく矛盾していませんか?

public class Main {
    public static void main(String[] args) {
        int a[] = new int[2];
        int i = a.length;
    }
}
ログイン後にコピー

クラスファイルを開いてメインメソッドのバイトコードを取得します:

0 iconst_2                   //将int型常量2压入操作数栈  
    1 newarray 10 (int)          //将2弹出操作数栈,作为长度,创建一个元素类型为int, 维度为1的数组,并将数组的引用压入操作数栈  
    3 astore_1                   //将数组的引用从操作数栈中弹出,保存在索引为1的局部变量(即a)中  
    4 aload_1                    //将索引为1的局部变量(即a)压入操作数栈  
    5 arraylength                //从操作数栈弹出数组引用(即a),并获取其长度(JVM负责实现如何获取),并将长度压入操作数栈  
    6 istore_2                   //将数组长度从操作数栈弹出,保存在索引为2的局部变量(即i)中  
    7 return                     //main方法返回
ログイン後にコピー

在这个字节码中我们还是没有看到length这个成员变量,但是看到了这个:arraylength ,这条指令是用来获取数组的长度的,所以说JVM对数组的长度做了特殊的处理,它是通过arraylength这条指令来实现的。

二、数组的使用方法

通过上面算是对数组是什么有了一个初步的认识,下面将简单介绍数组的使用方法。

数组的使用方法无非就是四个步骤:声明数组、分配空间、赋值、处理。

声明数组:就是告诉计算机数组的类型是什么。有两种形式:int[] array、int array[]。

分配空间:告诉计算机需要给该数组分配多少连续的空间,记住是连续的。array = new int[10];

赋值:赋值就是在已经分配的空间里面放入数据。array[0] = 1 、array[1] = 2……其实分配空间和赋值是一起进行的,也就是完成数组的初始化。有如下三种形式:

int a[] = new int[2];    //默认为0,如果是引用数据类型就为null
        int b[] = new int[] {1,2,3,4,5};    
        int c[] = {1,2,3,4,5};
ログイン後にコピー

       处理:就是对数组元素进行操作。通过数组名+有效的下标来确认数据。

以上就是java提高篇(十八)-----数组之一:认识JAVA数组 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート