Внимание к новым функциям в JDK 8 по праву сфокусировано на новых функциях и синтаксисе языка. Тем не менее, есть несколько приятных дополнений к библиотекам и API, и в этой статье я расскажу о четырех новых методах, добавленных в класс BigInteger : longValueExact () , intValueExact () , shortValueExact () и byteValueExact () .
Все четыре недавно представленных метода «xxxxxExact ()» выдают исключение ArithmeticException, если число, содержащееся в BigInteger
экземпляре, не может быть указано в указанной форме (указанной в имени метода) без потери информации. BigInteger
уже были методы intValue () и longValue (), а также унаследованные (от Number) методы shortValue () и byteValue () . Эти методы не генерируют исключения, если BigInteger
Значение теряет информацию в представлении как один из этих типов. Хотя на первый взгляд это может показаться преимуществом, это означает, что код, использующий результаты этих методов, использует значения, которые не являются точными без какой-либо возможности узнать, что информация была потеряна. Новые методы «xxxxxExact» ArithmenticException
скорее бросают , чем делают вид, что дают результат, который потерял значительную информацию.
Следующий простой код листинга демонстрирует «устаревшие» методы , которые представляют неверные данные в типах byte
, short
, int
и , long
а не бросать исключение. В этом же коде демонстрируется использование новых методов «xxxxxExact», которые выдают исключение при потере информации, а не представляют неверное представление. Выход выполнения этого кода следует код и демонстрирует , как методы ведут себя по- разному , когда BigInteger
содержит значение с большим количеством информации , чем возвращаемый byte
, short
, int
или long
может представлять.
BigIntegerDem.java
package dustin.examples.jdk8; import static java.lang.System.out; import java.math.BigInteger; /** * Demonstrate the four new methods of BigInteger introduced with JDK 8. * * @author Dustin */ public class BigIntegerDemo { /** * Demonstrate BigInteger.byteValueExact(). */ private static void demonstrateBigIntegerByteValueExact() { final BigInteger byteMax = new BigInteger(String.valueOf(Byte.MAX_VALUE)); out.println("Byte Max: " + byteMax.byteValue()); out.println("Byte Max: " + byteMax.byteValueExact()); final BigInteger bytePlus = byteMax.add(BigInteger.ONE); out.println("Byte Max + 1: " + bytePlus.byteValue()); out.println("Byte Max + 1: " + bytePlus.byteValueExact()); } /** * Demonstrate BigInteger.shortValueExact(). */ private static void demonstrateBigIntegerShortValueExact() { final BigInteger shortMax = new BigInteger(String.valueOf(Short.MAX_VALUE)); out.println("Short Max: " + shortMax.shortValue()); out.println("Short Max: " + shortMax.shortValueExact()); final BigInteger shortPlus = shortMax.add(BigInteger.ONE); out.println("Short Max + 1: " + shortPlus.shortValue()); out.println("Short Max + 1: " + shortPlus.shortValueExact()); } /** * Demonstrate BigInteger.intValueExact(). */ private static void demonstrateBigIntegerIntValueExact() { final BigInteger intMax = new BigInteger(String.valueOf(Integer.MAX_VALUE)); out.println("Int Max: " + intMax.intValue()); out.println("Int Max: " + intMax.intValueExact()); final BigInteger intPlus = intMax.add(BigInteger.ONE); out.println("Int Max + 1: " + intPlus.intValue()); out.println("Int Max + 1: " + intPlus.intValueExact()); } /** * Demonstrate BigInteger.longValueExact(). */ private static void demonstrateBigIntegerLongValueExact() { final BigInteger longMax = new BigInteger(String.valueOf(Long.MAX_VALUE)); out.println("Long Max: " + longMax.longValue()); out.println("Long Max: " + longMax.longValueExact()); final BigInteger longPlus = longMax.add(BigInteger.ONE); out.println("Long Max + 1: " + longPlus.longValue()); out.println("Long Max + 1: " + longPlus.longValueExact()); } /** * Demonstrate BigInteger's four new methods added with JDK 8. * * @param arguments Command line arguments. */ public static void main(final String[] arguments) { System.setErr(out); // exception stack traces to go to standard output try { demonstrateBigIntegerByteValueExact(); } catch (Exception exception) { exception.printStackTrace(); } try { demonstrateBigIntegerShortValueExact(); } catch (Exception exception) { exception.printStackTrace(); } try { demonstrateBigIntegerIntValueExact(); } catch (Exception exception) { exception.printStackTrace(); } try { demonstrateBigIntegerLongValueExact(); } catch (Exception exception) { exception.printStackTrace(); } } }
Выход
Byte Max: 127 Byte Max: 127 Byte Max + 1: -128 java.lang.ArithmeticException: BigInteger out of byte range at java.math.BigInteger.byteValueExact(BigInteger.java:4428) at dustin.examples.jdk8.BigIntegerDemo.demonstrateBigIntegerByteValueExact(BigIntegerDemo.java:23) at dustin.examples.jdk8.BigIntegerDemo.main(BigIntegerDemo.java:75) Short Max: 32767 Short Max: 32767 Short Max + 1: -32768 java.lang.ArithmeticException: BigInteger out of short range at java.math.BigInteger.shortValueExact(BigInteger.java:4407) at dustin.examples.jdk8.BigIntegerDemo.demonstrateBigIntegerShortValueExact(BigIntegerDemo.java:36) at dustin.examples.jdk8.BigIntegerDemo.main(BigIntegerDemo.java:84) Int Max: 2147483647 Int Max: 2147483647 Int Max + 1: -2147483648 java.lang.ArithmeticException: BigInteger out of int range at java.math.BigInteger.intValueExact(BigInteger.java:4386) at dustin.examples.jdk8.BigIntegerDemo.demonstrateBigIntegerIntValueExact(BigIntegerDemo.java:49) at dustin.examples.jdk8.BigIntegerDemo.main(BigIntegerDemo.java:93) Long Max: 9223372036854775807 Long Max: 9223372036854775807 Long Max + 1: -9223372036854775808 java.lang.ArithmeticException: BigInteger out of long range at java.math.BigInteger.longValueExact(BigInteger.java:4367) at dustin.examples.jdk8.BigIntegerDemo.demonstrateBigIntegerLongValueExact(BigIntegerDemo.java:62) at dustin.examples.jdk8.BigIntegerDemo.main(BigIntegerDemo.java:102)
As the above output demonstrates, the new BigInteger methods with «xxxxxExact» in their name will not present inaccurate representations when the returned type cannot hold the information in BigInteger
instance. Although exceptions are generally not one of our favorite things, they are almost always going to be better than getting and using wrong data and not even realizing it is wrong.