isAssignableFrom と CastTo.cast を使って、型安全にキャストする方法をまとめます。
背景
Javaではキャスト時に型が合わないと ClassCastException が発生します。
特に Object 型やジェネリクスの値を扱う場合、型チェックとキャストを安全に行う必要があります。
Class.isAssignableFrom
isAssignableFrom は「ある型が他の型か親かどうか」を確認できます。
CastTo.cast
CastTo.castでobjを安全にT型にキャストする
public <T extends Constant> T getConstant(final int index, final Class<T> castTo) throws ClassFormatException {
if (index >= constantPool.length || index < 1) {
throw new ClassFormatException("Invalid constant pool reference using index: " + index + ". Constant pool size is: " + constantPool.length);
}
if (constantPool[index] != null && !castTo.isAssignableFrom(constantPool[index].getClass())) {
throw new ClassFormatException("Invalid constant pool reference at index: " + index +
". Expected " + castTo + " but was " + constantPool[index].getClass());
}
if (index > 1) {
final Constant prev = constantPool[index - 1];
if (prev != null && (prev.getTag() == Const.CONSTANT_Double || prev.getTag() == Const.CONSTANT_Long)) {
throw new ClassFormatException("Constant pool at index " + index + " is invalid. The index is unused due to the preceeding "
+ Const.getConstantName(prev.getTag()) + ".");
}
}
// Previous check ensures this won't throw a ClassCastException
final T c = castTo.cast(constantPool[index]);
if (c == null) {
throw new ClassFormatException("Constant pool at index " + index + " is null.");
}
return c;
}
instanceof との違い
| 特徴 | instanceof |
CastTo.cast |
|---|---|---|
| 型チェック | ○ | ○ |
| キャスト | ×(戻り値は boolean) | ○(指定型で返却) |
null の扱い |
null instanceof AnyClass → false |
cast(null, AnyClass) → nullを返す |
| 型不一致時の挙動 | 例外なし | ClassCastException 発生 |
まとめ
isAssignableFrom → 型互換性の確認用
CastTo.cast → 安全なキャスト(nullはそのまま返却、型不一致は例外)
instanceof だけではキャストできないが、例外は発生しない
instanceOfでキャストする場合はnullチェックが必要