20

このコードは有効です

int h;
byte r;
h=r;

しかし、これらはそうではありません

int[] h;
byte[] r;
h=r;

または言う

int[] h =new byte[4];

なぜ知りたいのですか?

4

6 に答える 6

24

からへの暗黙的な変換がありますが、 からへのbyte変換はありません。これは非常に理にかなっています.JITコンパイラは、 の値を取得するには、インデックスに4を掛けて、それをデータの先頭に追加するだけでよいことを認識しています(もちろん、検証後、余分なパディングはないと仮定します)。 )。変数への参照を割り当てることができる場合、それは機能しません-表現が異なります。intbyte[]int[]int[]byte[]int[]

言語は、その変換を許可するように設計されている可能性がありますが、すべてのバイトのコピーを含む新しいものを作成しますが、代入演算子 が単にコピーする Java の残りの部分の設計に関しては、かなり驚くべきことでした演算子の右側から左側の変数への値。int[]

あるいは、すべての配列アクセスが問題の配列オブジェクトの実際の型を見て、要素に適切に到達する方法を考え出さなければならないという制限を VM に課すこともできました... しかし、それは恐ろしいことでした (参照型配列の共分散の現在の厄介さよりもさらに悪い)。

于 2013-07-28T13:31:51.773 に答える
12

それがデザインです。wide に割り当てるbyteと、それで問題ありませんint。しかし、宣言するnew byte[4]と、それはメモリの ["連続した"] 部分であり、大まかに言えば、4 * 8 ビット (または 4 バイト) に相当します。1 つintは 32 ビットなので、技術的には、すべてのbyte配列のサイズは one のサイズに等しくなりますint。メモリに直接アクセスできる C では、ポインター マジックを実行して、byteポインターをポインターにキャストすることができintます。Java ではできません。安全です。

とにかく、なぜそれが欲しいのですか?免責事項: 以下のコードは、パフォーマンスが重要な一部のライブラリ/アプリの最も重要なセクションを除いて、どこにも見られる可能性は非常に低いと考えられています。イデオネ: http://ideone.com/e14Omr

コメントは十分に説明的です。

import sun.misc.Unsafe;
import java.lang.reflect.Field;

public class Main {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
        /* too lazy to run with VM args, use Reflection */
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        /* get array address */
        Unsafe unsafe = (Unsafe)f.get(null);
        byte four_bytes[] = {25, 25, 25, 25};
        Object trash[] = new Object[] { four_bytes };
        long base_offset_bytes = unsafe.arrayBaseOffset(Object[].class);
        long four_bytes_address = unsafe.getLong(trash, base_offset_bytes); // <- this is it
        long ints_addr = unsafe.allocateMemory(16); // allocate 4 * 4 bytes, i.e. 4 ints
        unsafe.copyMemory(four_bytes_address + base_offset_bytes, ints_addr, 4); // copy all four bytes
        for(int i = 0; i < 4; i++) {
            System.out.println(unsafe.getInt(ints_addr + i)); //run through entire allocated int[],
                                                              // get some intestines
        }
        System.out.println("*****************************");
        for(int i = 0; i < 16; i++) {
            System.out.println(unsafe.getByte(ints_addr + i)); //run through entire allocated int[],
                                                              // get some intestines
        }
    }
}
于 2013-07-28T13:33:42.497 に答える
1

単純に、Type byte[] は int[] を拡張しません

于 2013-07-28T13:33:25.330 に答える
-1

大きな要素が小さな要素に格納されるため、できません。整数はバイトに格納できません。これらのタイプの割り当てを決定するメモリ設計

于 2013-07-28T18:55:21.170 に答える