库中的函数返回一个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
是对对象的引用,而不是对象。您可以更改引用的类型,但不能使用 cast 来更改或创建新对象。
有四种方法可以从您真正想要的对象转换对象:intValue
、longValue
和。只需选择最适合您的一款,您就可以开始使用了。floatValue
doubleValue
您会注意到基元的引用类型都实现了接口intValue()
上的抽象方法(它们几乎都以相同的方式实现) 。Number
(
例如,Integer
(which extends 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;
}
因此,当您引用 aNumber
时,您可以这样做
Number n = ...;
int value = n.intValue();
它将多态地调用动态类型的方法。
您可以随时检查类型Number
并进行投射
Number n = ...;
if (n instanceof Integer)
Integer i = (Integer) n;
Number
是 Java 中用于声明“数字”类型的许多其他类的超类。它主要用于泛型以及当您需要使用超类的引用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
,但您可以将其强制转换为Integer
(假设它是对 an 的引用Integer
)(并且Integer
只是 的包装类int
,Java 使用拆箱,它允许您本质上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 所提到的,如果 a 不引用 a (例如,它也可以引用 a ),您ClassCastException
将Number
得到Integer
a Double
。为避免这种情况,您可以
if (n instanceof Integer)
在尝试投射之前进行检查。
或者您可以使用xxxValue
其他一些答案中建议的函数(这应该避免需要检查它的实例,因为所有类都需要实现所有xxxValue
函数(因为它们abstract
在 中Number
),尽管理论上这些可以实现为抛出异常,尽管我怀疑标准 API 中的任何类都会这样做)。
我建议在函数之上进行强制转换的原因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());