5

以下のプログラムでは、なぜClassCastExceptionキャストが存在するのか理解できませんint.class

更新: プリミティブ型が何であるかを知っていることを指定する必要があります。What I don't understand is why int.class is provided with broken implementation?

  public static void main(String[] args) {
    System.out.println(DataType.INT.getValue(Integer.class));
    System.out.println(DataType.INT.getValue(int.class));//Class cast exception here
}

enum DataType {
    INT {
        @Override
        public <T> T getValue(Class<T> toClass) {
            return toClass.cast(1000);//ClassCastException here for int.class
        }
    };
    public abstract <T> T getValue(Class<T> toClass);

}
4

6 に答える 6

3

これは、cast()の操作がisInstance()Classを使用するために発生します。 method which returns false for primitive classes

この Class オブジェクトがプリミティブ型を表す場合、このメソッドは false を返します。

メソッドのコードcast()は以下です

public T cast(Object obj) {
if (obj != null && !isInstance(obj))//It fails here since isInstance returns false
    throw new ClassCastException();
return (T) obj;
于 2012-10-21T06:13:48.723 に答える
3

わかりました、いくつかのリンクをたどり、いくつかのコードを試した後、次のことがわかりました:-

  • int.class== Integer.TYPE== 整数
  • int.class!=Integer.class

したがって、 の値はint.classtype を表す Class オブジェクトintです。

したがって、DataType.INTwithを呼び出すとint.class、呼び出すことができないtoClasscontentが含まれます。クラスから拡張されていないためかもしれません。メソッドは、呼び出し元の型が型であるかどうかを内部的にチェックするために使用されるためです。intcastObjectcastisinstanceObject

public T cast(Object obj) {
if (obj != null && !isInstance(obj))
    throw new ClassCastException();
return (T) obj;
}

したがって、呼び出す型がcastのインスタンスでない場合Object(もちろんprimitive型はそうではありません)、 が返されるfalseため、が返されClassCastExceptionます。

于 2012-10-21T05:37:30.687 に答える
0

私はこれが起こっていることだと思います:

を呼び出すreturn toClass.cast(1000);と、リテラル1000はに昇格しIntegerます。プロモーションルールはここに記載されています:Java言語仕様

ここで、castメソッドが呼び出されるとintClass、argument(1000)が同じインスタンスであるかどうかがチェックされます。つまりint.class、そうでないために失敗します。

一方、にキャストするとInteger.class、インスタンスタイプが一致するため、成功します。

だから、文字通りのClassCastExceptionせいで来ている。Promotion1000Integer

于 2012-10-21T06:24:34.823 に答える
0

int.classと同じではないからだと思いますInteger.class

アップデート


キャスト メソッドを見ることができます。パラメータは であるObjectため、1000 が自動ボックス化されることは明らかです。したがって、メソッドへの実際の引数は のインスタンスですInteger

public T cast(Object obj) {
if (obj != null && !isInstance(obj))
    throw new ClassCastException();
return (T) obj;
}
于 2012-10-21T05:46:55.943 に答える
0

Integerintは値のクラス ラッパーですが、クラスintではなくプリミティブ型です。クラスを使用する必要があるコードなどで、プリミティブ型とクラスを混同しないでください。

List<int> lstInteger; //won't compile!
List<Integer> lstInteger; //compiles fine

より詳しい情報:


int型はプリミティブな C/C++ int 型と考えてください。これを知っていると、 int はクラスではないため、属性もメソッドも持たず、整数値を保持するだけです。一方、プリミティブ型java.lang.Integerのクラスラッパーです。intこれは、intオブジェクト インスタンスしか使用できない場合に使用するためです。これの良い例は、クラスに対してのみ機能する Java の汎用システムです (コード例で提案されているように)。

この詳細については、Oracle Java チュートリアル:プリミティブ データ型を参照してください。

于 2012-10-21T05:37:27.097 に答える