制限、Integer.MAX_VALUE(=2^31 - 1)の壁

やっぱりJavaではInteger.MAX_VALUEを超える要素数を持った配列ってつくれないよね.(byte[Integer.MAX_VALUE]という変数だけでヒープサイズを2GB消費するのは置いておくと)

JavaSEのJavaDocのいろんなクラスを見渡しても,capacityやlengthを指定するような個所は全てint型なわけでありlong型ではない.Integer.MAX_VALUE(=2^31-1)を超えるサイズはJavaSEのレベルで指定不可能.

まいった・・・.



いろんな数字を見てみる.

    public static void main(String[] args) throws Exception {
        long[] v = new long[10];
        v[0] = Long.MAX_VALUE;
        v[1] = (1L<<31) - 1;  // = Integer.MAX_VALUE のlong型表現
        v[2] = 1L<<31;        // = Integer.MAX_VALUEより1大きい
        v[3] = 1L<<32;
        v[4] = 1L<<33;
        v[5] = (1L<<33) + 10000;
        v[6] = 1L<<40;
        v[7] = 1L<<48;
        v[8] = (1L<<63) - 1;  // = Long.MAX_VALUE
        v[9] = (1L<<63);      // = Long.MAX_VALUEより1大きい   
        
        for (int i = 0; i < v.length; i++) {
            System.out.println("v[" + i + "], " + v[i] + ", " + (int) v[i]);
        }
    }

縮小変換をすると値は予測不能って感じ.これはJVM実装依存

v[0], 9223372036854775807, -1
v[1], 2147483647, 2147483647
v[2], 2147483648, -2147483648
v[3], 4294967296, 0
v[4], 8589934592, 0
v[5], 8589944592, 10000
v[6], 1099511627776, 0
v[7], 281474976710656, 0
v[8], 9223372036854775807, -1
v[9], -9223372036854775808, 0

で,Integer.MAX_VALUEよりも大きなサイズのストリーム(2GB以上)でも適切に扱いなさいとJDBC 4.0仕様は仰っているわけだが,どうしよう・・・.

ストリームのサイズを指定せずに,順次読み取りを行って,バッファと同じサイズだけ蓄積するごとにサーバに送信,サーバもサイズは一切不干渉のままでストレージに格納,なんて感じで全て上手くいくようになってないと無理なんじゃ….