ライブラリの関数は を返しますNumber
。使用可能なものに変換できず (「Number から int に変換できません」)、 を使用して印刷できませんString.format
。をどのように処理しNumber
ますか?
7 に答える
使えるものに変換できない
もちろんできます!
void doSomething(Number myNumber) {
int intNumber = myNumber.intValue();
double dblNumber = myNumber.doubleValue();
// Now do something useful
}
クラスの背後にある考え方Number
は、組み込みの数値型に共通のスーパークラスを与えることです。数値を渡す際の柔軟性が向上するため、使用する型の決定は、数値が必要になるまで延期できます。
これは、データ取得用のコードが数値データを使用するコードから分離されている場合に特に役立ちます。取得コードは、特定の型を気にせずに、型指定されていない数値に関して操作できるためです。
あなたはできる
- 基になる型にキャストする
- プリミティブ型に変換します
- toString() で。例: String.format("%s", number);
一般的に、それはそれほど有用な私見ではありません。
double
私は「スーパープリミティブ」タイプとして使用することを好みます。または BigDecimal/BigInteger がオプションでない場合。
しかし、とにかくそれらの関数が存在する場合、キャストできないのはなぜですか?
Number
オブジェクトではなく、オブジェクトへの参照です。参照の型は変更できますが、キャストを使用して新しいオブジェクトを変更または作成することはできません。
プリミティブの Reference 型はすべて、インターフェイスintValue()
上で抽象化されている (ほとんど同じ方法で実装されている)ようなメソッドを実装していることに気付くでしょう。Number
(
たとえば、Integer
(これは を拡張しますNumber
) は
/**
* Returns the value of this {@code Integer} as a
* {@code long}.
*/
public long longValue() {
return (long)value;
}
/**
* Returns the value of this {@code Integer} as a
* {@code float}.
*/
public float floatValue() {
return (float)value;
}
/**
* Returns the value of this {@code Integer} as a
* {@code double}.
*/
public double doubleValue() {
return (double)value;
}
したがって、 a への参照がある場合はNumber
、次のことができます
Number n = ...;
int value = n.intValue();
動的型のメソッドをポリモーフィックに呼び出します。
いつでも型Number
とキャストを確認できます
Number n = ...;
if (n instanceof Integer)
Integer i = (Integer) n;
Number
「数値」型を宣言するために使用されるJavaの他の多くのクラスのスーパークラスです。これは主に Generics で使用され、Collections
ポリモーフィズムを利用するためにスーパー クラスの参照を使用する必要がある場合に使用されます。
class A<T extends Number>{
}
また
List<Number> list = new ArrayList<>();
list.add(new Integer("1"));
list.add(new Double("1.1"));
...
Number n = library.function();
int i = n.intValue();
System.out.print(i);
にキャストすることはできませんが、 ( への参照であると仮定して)int
にキャストすることはできます(これは単なる のラッパー クラスであり、Java はアンボックス化を使用して、本質的に として使用できます) 。Integer
Integer
Integer
int
Integer
int
動作しません:
Number n = 3;
System.out.println(3 + (int)n);
作品:
// autoboxing int(3) to Integer(3) and creating a reference of type Number to it
Number n = 3;
// unboxing Integer(3) to int(3) and adding it to int(2)
System.out.println(2 + (Integer)n);
cHao が述べたように、 がan を参照しないClassCastException
場合はa を取得します(たとえば、 a も参照できます)。これを回避するには、キャストを試みる前に確認できます。Number
Integer
Double
if (n instanceof Integer)
または、他のいくつかの回答で提案されているように関数を使用できます(これにより、すべてのクラスがすべての関数xxxValue
を実装する必要があるため( にあるように)、インスタンスが何であるかを確認する必要がなくなります)。ただし、これらは理論的には実装できます例外をスローしますが、標準 API のクラスがこれを行うとは思えません)。xxxValue
abstract
Number
私が関数の上にキャストすることを提案した理由xxxValue
は、別の型の値を喜んで返すのとは対照的に、これがあなたが望む型を明示的にするからです。次の例を検討してください。
Number n = 3.9999999; // that's rather close to 4
// prints '3' as double to int conversion rounds down
System.out.println(n.intValue());
// returns false
if (n instanceof Integer)
// would've thrown exception
System.out.println((Integer)n);
else
// prints '3.9999999 is not an integer! It is a Double'
System.out.println(n + " is not an integer!! It is a " + n.getClass().getSimpleName());