2

库中的函数返回一个Number. 我无法将其转换为任何可用的东西(“无法从 Number 转换为 int”),也无法使用String.format. 我该如何处理Number

4

7 回答 7

5

我无法将其转换为任何可用的东西

当然可以!

void doSomething(Number myNumber) {
    int intNumber = myNumber.intValue();
    double dblNumber = myNumber.doubleValue();
    // Now do something useful
}

该类背后的想法Number是为内置数字类型提供一个通用超类。它为您传递数字提供了更大的灵活性,因此可以将决定使用哪种类型的决定推迟到需要数值的那一刻。

当数据检索的代码与使用数字数据的代码分开时,这变得特别有用,因为检索代码可以根据未键入的数字进行操作,而不用担心特定的类型。

于 2013-09-04T14:17:49.527 回答
2

你可以

  • 将其转换为其基础类型
  • 将其转换为原始类型
  • toString() 。例如 String.format("%s", number);

一般来说,恕我直言,它不是那么有用。

我更喜欢double用作“超级原始”类型。或 BigDecimal/BigInteger 如果这不是一个选项。

但是,如果这些功能仍然存在,为什么不能强制转换呢?

Number是对对象的引用,而不是对象。您可以更改引用的类型,但不能使用 cast 来更改或创建新对象。

于 2013-09-04T14:17:42.983 回答
2

有四种方法可以从您真正想要的对象转换对象:intValuelongValue和。只需选择最适合您的一款,您就可以开始使用了。floatValuedoubleValue

于 2013-09-04T14:18:24.373 回答
1

您会注意到基元的引用类型都实现了接口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;
于 2013-09-04T14:20:11.960 回答
1

Number是 Java 中用于声明“数字”类型的许多其他类的超类。它主要用于泛型以及当您需要使用超类的引用Collections以利用多态性时:

class A<T extends Number>{
}

或者

List<Number> list = new ArrayList<>();
list.add(new Integer("1"));
list.add(new Double("1.1"));
...
于 2013-09-04T14:20:56.777 回答
0
   Number n = library.function();
   int i = n.intValue();
   System.out.print(i);
于 2013-09-04T14:20:21.367 回答
0

您不能将其强制转换为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 ),您ClassCastExceptionNumber得到Integera 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());
于 2013-09-04T14:20:40.153 回答