src/share/classes/java/lang/Integer.java

Print this page
rev 9892 : imported patch format.diff
rev 9893 : 8041972: Add improved parse methods for Long/Integer


   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang;
  27 
  28 import java.lang.annotation.Native;

  29 
  30 /**
  31  * The {@code Integer} class wraps a value of the primitive type
  32  * {@code int} in an object. An object of type {@code Integer}
  33  * contains a single field whose type is {@code int}.
  34  *
  35  * <p>In addition, this class provides several methods for converting
  36  * an {@code int} to a {@code String} and a {@code String} to an
  37  * {@code int}, as well as other constants and methods useful when
  38  * dealing with an {@code int}.
  39  *
  40  * <p>Implementation note: The implementations of the "bit twiddling"
  41  * methods (such as {@link #highestOneBit(int) highestOneBit} and
  42  * {@link #numberOfTrailingZeros(int) numberOfTrailingZeros}) are
  43  * based on material from Henry S. Warren, Jr.'s <i>Hacker's
  44  * Delight</i>, (Addison Wesley, 2002).
  45  *
  46  * @author  Lee Boynton
  47  * @author  Arthur van Hoff
  48  * @author  Josh Bloch


 538         /*
 539          * WARNING: This method may be invoked early during VM initialization
 540          * before IntegerCache is initialized. Care must be taken to not use
 541          * the valueOf method.
 542          */
 543 
 544         if (s == null) {
 545             throw new NumberFormatException("null");
 546         }
 547 
 548         if (radix < Character.MIN_RADIX) {
 549             throw new NumberFormatException("radix " + radix +
 550                                             " less than Character.MIN_RADIX");
 551         }
 552 
 553         if (radix > Character.MAX_RADIX) {
 554             throw new NumberFormatException("radix " + radix +
 555                                             " greater than Character.MAX_RADIX");
 556         }
 557 
 558         int result = 0;
 559         boolean negative = false;
 560         int i = 0, len = s.length();
 561         int limit = -Integer.MAX_VALUE;
 562         int multmin;
 563         int digit;
 564 
 565         if (len > 0) {
 566             char firstChar = s.charAt(0);
 567             if (firstChar < '0') { // Possible leading "+" or "-"
 568                 if (firstChar == '-') {
 569                     negative = true;
 570                     limit = Integer.MIN_VALUE;
 571                 } else if (firstChar != '+')
 572                     throw NumberFormatException.forInputString(s);

 573 
 574                 if (len == 1) // Cannot have lone "+" or "-"
 575                     throw NumberFormatException.forInputString(s);

 576                 i++;
 577             }
 578             multmin = limit / radix;

 579             while (i < len) {
 580                 // Accumulating negatively avoids surprises near MAX_VALUE
 581                 digit = Character.digit(s.charAt(i++),radix);
 582                 if (digit < 0) {
 583                     throw NumberFormatException.forInputString(s);
 584                 }
 585                 if (result < multmin) {
 586                     throw NumberFormatException.forInputString(s);
 587                 }
 588                 result *= radix;
 589                 if (result < limit + digit) {
 590                     throw NumberFormatException.forInputString(s);
 591                 }
 592                 result -= digit;
 593             }

 594         } else {
 595             throw NumberFormatException.forInputString(s);
 596         }
















































































































 597         return negative ? result : -result;



 598     }
 599 
 600     /**
 601      * Parses the string argument as a signed decimal integer. The
 602      * characters in the string must all be decimal digits, except
 603      * that the first character may be an ASCII minus sign {@code '-'}
 604      * ({@code '\u005Cu002D'}) to indicate a negative value or an
 605      * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to
 606      * indicate a positive value. The resulting integer value is
 607      * returned, exactly as if the argument and the radix 10 were
 608      * given as arguments to the {@link #parseInt(java.lang.String,
 609      * int)} method.
 610      *
 611      * @param s    a {@code String} containing the {@code int}
 612      *             representation to be parsed
 613      * @return     the integer value represented by the argument in decimal.
 614      * @exception  NumberFormatException  if the string does not contain a
 615      *               parsable integer.
 616      */
 617     public static int parseInt(String s) throws NumberFormatException {


 674                 throw new
 675                     NumberFormatException(String.format("Illegal leading minus sign " +
 676                                                        "on unsigned string %s.", s));
 677             } else {
 678                 if (len <= 5 || // Integer.MAX_VALUE in Character.MAX_RADIX is 6 digits
 679                     (radix == 10 && len <= 9) ) { // Integer.MAX_VALUE in base 10 is 10 digits
 680                     return parseInt(s, radix);
 681                 } else {
 682                     long ell = Long.parseLong(s, radix);
 683                     if ((ell & 0xffff_ffff_0000_0000L) == 0) {
 684                         return (int) ell;
 685                     } else {
 686                         throw new
 687                             NumberFormatException(String.format("String value %s exceeds " +
 688                                                                 "range of unsigned int.", s));
 689                     }
 690                 }
 691             }
 692         } else {
 693             throw NumberFormatException.forInputString(s);





























































































 694         }
 695     }
 696 
 697     /**
 698      * Parses the string argument as an unsigned decimal integer. The
 699      * characters in the string must all be decimal digits, except
 700      * that the first character may be an an ASCII plus sign {@code
 701      * '+'} ({@code '\u005Cu002B'}). The resulting integer value
 702      * is returned, exactly as if the argument and the radix 10 were
 703      * given as arguments to the {@link
 704      * #parseUnsignedInt(java.lang.String, int)} method.
 705      *
 706      * @param s   a {@code String} containing the unsigned {@code int}
 707      *            representation to be parsed
 708      * @return    the unsigned integer value represented by the argument in decimal.
 709      * @throws    NumberFormatException  if the string does not contain a
 710      *            parsable unsigned integer.
 711      * @since 1.8
 712      */
 713     public static int parseUnsignedInt(String s) throws NumberFormatException {




   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang;
  27 
  28 import java.lang.annotation.Native;
  29 import java.util.Objects;
  30 
  31 /**
  32  * The {@code Integer} class wraps a value of the primitive type
  33  * {@code int} in an object. An object of type {@code Integer}
  34  * contains a single field whose type is {@code int}.
  35  *
  36  * <p>In addition, this class provides several methods for converting
  37  * an {@code int} to a {@code String} and a {@code String} to an
  38  * {@code int}, as well as other constants and methods useful when
  39  * dealing with an {@code int}.
  40  *
  41  * <p>Implementation note: The implementations of the "bit twiddling"
  42  * methods (such as {@link #highestOneBit(int) highestOneBit} and
  43  * {@link #numberOfTrailingZeros(int) numberOfTrailingZeros}) are
  44  * based on material from Henry S. Warren, Jr.'s <i>Hacker's
  45  * Delight</i>, (Addison Wesley, 2002).
  46  *
  47  * @author  Lee Boynton
  48  * @author  Arthur van Hoff
  49  * @author  Josh Bloch


 539         /*
 540          * WARNING: This method may be invoked early during VM initialization
 541          * before IntegerCache is initialized. Care must be taken to not use
 542          * the valueOf method.
 543          */
 544 
 545         if (s == null) {
 546             throw new NumberFormatException("null");
 547         }
 548 
 549         if (radix < Character.MIN_RADIX) {
 550             throw new NumberFormatException("radix " + radix +
 551                                             " less than Character.MIN_RADIX");
 552         }
 553 
 554         if (radix > Character.MAX_RADIX) {
 555             throw new NumberFormatException("radix " + radix +
 556                                             " greater than Character.MAX_RADIX");
 557         }
 558 

 559         boolean negative = false;
 560         int i = 0, len = s.length();
 561         int limit = -Integer.MAX_VALUE;


 562 
 563         if (len > 0) {
 564             char firstChar = s.charAt(0);
 565             if (firstChar < '0') { // Possible leading "+" or "-"
 566                 if (firstChar == '-') {
 567                     negative = true;
 568                     limit = Integer.MIN_VALUE;
 569                 } else if (firstChar != '+') {
 570                     throw NumberFormatException.forInputString(s);
 571                 }
 572 
 573                 if (len == 1) { // Cannot have lone "+" or "-"
 574                     throw NumberFormatException.forInputString(s);
 575                 }
 576                 i++;
 577             }
 578             int multmin = limit / radix;
 579             int result = 0;
 580             while (i < len) {
 581                 // Accumulating negatively avoids surprises near MAX_VALUE
 582                 int digit = Character.digit(s.charAt(i++), radix);
 583                 if (digit < 0 || result < multmin) {



 584                     throw NumberFormatException.forInputString(s);
 585                 }
 586                 result *= radix;
 587                 if (result < limit + digit) {
 588                     throw NumberFormatException.forInputString(s);
 589                 }
 590                 result -= digit;
 591             }
 592             return negative ? result : -result;
 593         } else {
 594             throw NumberFormatException.forInputString(s);
 595         }
 596     }
 597 
 598     /**
 599      * Parses the {@link CharSequence} argument as a signed {@code int} in the
 600      * specified {@code radix}, beginning at the specified {@code beginIndex}
 601      * and extending to the end of the sequence.
 602      *
 603      * <p>The method does not take steps to guard against the
 604      * {@code CharSequence} being mutated while parsing.
 605      *
 606      * @param      s   the {@code CharSequence} containing the {@code int}
 607      *                  representation to be parsed
 608      * @param      radix   the radix to be used while parsing {@code s}.
 609      * @param      beginIndex   the beginning index, inclusive.
 610      * @return     the signed {@code int} represented by the subsequence in
 611      *             the specified radix.
 612      * @throws     NullPointerException  if {@code s} is null.
 613      * @throws     IndexOutOfBoundsException  if {@code beginIndex} is
 614      *             negative, or if {@code beginIndex} is greater than
 615      *             {@code s.length()}.
 616      * @throws     NumberFormatException  if the {@code CharSequence} does not
 617      *             contain a parsable {@code int} in the specified
 618      *             {@code radix}, or if {@code radix} is either smaller than
 619      *             {@link java.lang.Character#MIN_RADIX} or larger than
 620      *             {@link java.lang.Character#MAX_RADIX}.
 621      * @since  1.9
 622      */
 623     static int parseInt(CharSequence s, int radix, int beginIndex)
 624                 throws NumberFormatException {
 625         // forces an implicit null check of s
 626         return parseInt(s, radix, beginIndex, s.length());
 627     }
 628 
 629     /**
 630      * Parses the {@link CharSequence} argument as a signed {@code int} in the
 631      * specified {@code radix}, beginning at the specified {@code beginIndex}
 632      * and extending to {@code endIndex - 1}.
 633      *
 634      * <p>The method does not take steps to guard against the
 635      * {@code CharSequence} being mutated while parsing.
 636      *
 637      * @param      s   the {@code CharSequence} containing the {@code int}
 638      *                  representation to be parsed
 639      * @param      radix   the radix to be used while parsing {@code s}.
 640      * @param      beginIndex   the beginning index, inclusive.
 641      * @param      endIndex     the ending index, exclusive.
 642      * @return     the signed {@code int} represented by the subsequence in
 643      *             the specified radix.
 644      * @throws     NullPointerException  if {@code s} is null.
 645      * @throws     IndexOutOfBoundsException  if {@code beginIndex} is
 646      *             negative, or if {@code beginIndex} is greater than
 647      *             {@code endIndex} or if {@code endIndex} is greater than
 648      *             {@code s.length()}.
 649      * @throws     NumberFormatException  if the {@code CharSequence} does not
 650      *             contain a parsable {@code int} in the specified
 651      *             {@code radix}, or if {@code radix} is either smaller than
 652      *             {@link java.lang.Character#MIN_RADIX} or larger than
 653      *             {@link java.lang.Character#MAX_RADIX}.
 654      * @since  1.9
 655      */
 656     static int parseInt(CharSequence s, int radix, int beginIndex, int endIndex)
 657                 throws NumberFormatException {
 658         s = Objects.requireNonNull(s);
 659 
 660         if (beginIndex < 0 || beginIndex > endIndex || endIndex > s.length()) {
 661             throw new IndexOutOfBoundsException();
 662         }
 663         if (radix < Character.MIN_RADIX) {
 664             throw new NumberFormatException("radix " + radix +
 665                                             " less than Character.MIN_RADIX");
 666         }
 667         if (radix > Character.MAX_RADIX) {
 668             throw new NumberFormatException("radix " + radix +
 669                                             " greater than Character.MAX_RADIX");
 670         }
 671 
 672         boolean negative = false;
 673         int i = beginIndex;
 674         int limit = -Integer.MAX_VALUE;
 675 
 676         if (i < endIndex) {
 677             char firstChar = s.charAt(i);
 678             if (firstChar < '0') { // Possible leading "+" or "-"
 679                 if (firstChar == '-') {
 680                     negative = true;
 681                     limit = Integer.MIN_VALUE;
 682                 } else if (firstChar != '+') {
 683                     throw NumberFormatException.forCharSequence(s, beginIndex,
 684                             endIndex, i);
 685                 }
 686                 i++;
 687                 if (i == endIndex) { // Cannot have lone "+" or "-"
 688                     throw NumberFormatException.forCharSequence(s, beginIndex,
 689                             endIndex, i);
 690                 }
 691             }
 692             int multmin = limit / radix;
 693             int result = 0;
 694             while (i < endIndex) {
 695                 // Accumulating negatively avoids surprises near MAX_VALUE
 696                 int digit = Character.digit(s.charAt(i++), radix);
 697                 if (digit < 0 || result < multmin) {
 698                     throw NumberFormatException.forCharSequence(s, beginIndex,
 699                             endIndex, i);
 700                 }
 701                 result *= radix;
 702                 if (result < limit + digit) {
 703                     throw NumberFormatException.forCharSequence(s, beginIndex,
 704                             endIndex, i);
 705                 }
 706                 result -= digit;
 707             }
 708             return negative ? result : -result;
 709         } else {
 710             throw NumberFormatException.forInputString("");
 711         }
 712     }
 713 
 714     /**
 715      * Parses the string argument as a signed decimal integer. The
 716      * characters in the string must all be decimal digits, except
 717      * that the first character may be an ASCII minus sign {@code '-'}
 718      * ({@code '\u005Cu002D'}) to indicate a negative value or an
 719      * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to
 720      * indicate a positive value. The resulting integer value is
 721      * returned, exactly as if the argument and the radix 10 were
 722      * given as arguments to the {@link #parseInt(java.lang.String,
 723      * int)} method.
 724      *
 725      * @param s    a {@code String} containing the {@code int}
 726      *             representation to be parsed
 727      * @return     the integer value represented by the argument in decimal.
 728      * @exception  NumberFormatException  if the string does not contain a
 729      *               parsable integer.
 730      */
 731     public static int parseInt(String s) throws NumberFormatException {


 788                 throw new
 789                     NumberFormatException(String.format("Illegal leading minus sign " +
 790                                                        "on unsigned string %s.", s));
 791             } else {
 792                 if (len <= 5 || // Integer.MAX_VALUE in Character.MAX_RADIX is 6 digits
 793                     (radix == 10 && len <= 9) ) { // Integer.MAX_VALUE in base 10 is 10 digits
 794                     return parseInt(s, radix);
 795                 } else {
 796                     long ell = Long.parseLong(s, radix);
 797                     if ((ell & 0xffff_ffff_0000_0000L) == 0) {
 798                         return (int) ell;
 799                     } else {
 800                         throw new
 801                             NumberFormatException(String.format("String value %s exceeds " +
 802                                                                 "range of unsigned int.", s));
 803                     }
 804                 }
 805             }
 806         } else {
 807             throw NumberFormatException.forInputString(s);
 808         }
 809     }
 810 
 811     /**
 812      * Parses the {@link CharSequence} argument as an unsigned {@code int} in
 813      * the specified {@code radix}, beginning at the specified
 814      * {@code beginIndex} and extending to the end of the sequence.
 815      *
 816      * <p>The method does not take steps to guard against the
 817      * {@code CharSequence} being mutated while parsing.
 818      *
 819      * @param      s   the {@code CharSequence} containing the unsigned
 820      *                 {@code int} representation to be parsed
 821      * @param      radix   the radix to be used while parsing {@code s}.
 822      * @param      beginIndex   the beginning index, inclusive.
 823      * @return     the unsigned {@code int} represented by the subsequence in
 824      *             the specified radix.
 825      * @throws     NullPointerException  if {@code s} is null.
 826      * @throws     IndexOutOfBoundsException  if {@code beginIndex} is
 827      *             negative, or if {@code beginIndex} is greater than
 828      *             {@code s.length()}.
 829      * @throws     NumberFormatException  if the {@code CharSequence} does not
 830      *             contain a parsable unsigned {@code int} in the specified
 831      *             {@code radix}, or if {@code radix} is either smaller than
 832      *             {@link java.lang.Character#MIN_RADIX} or larger than
 833      *             {@link java.lang.Character#MAX_RADIX}.
 834      * @since  1.9
 835      */
 836     static int parseUnsignedInt(CharSequence s, int radix, int beginIndex)
 837                 throws NumberFormatException {
 838         // forces an implicit null check of s
 839         return parseUnsignedInt(s, radix, beginIndex, s.length());
 840     }
 841 
 842     /**
 843      * Parses the {@link CharSequence} argument as an unsigned {@code int} in
 844      * the specified {@code radix}, beginning at the specified
 845      * {@code beginIndex} and extending to {@code endIndex - 1}.
 846      *
 847      * <p>The method does not take steps to guard against the
 848      * {@code CharSequence} being mutated while parsing.
 849      *
 850      * @param      s   the {@code CharSequence} containing the unsigned
 851      *                 {@code int} representation to be parsed
 852      * @param      radix   the radix to be used while parsing {@code s}.
 853      * @param      beginIndex   the beginning index, inclusive.
 854      * @param      endIndex     the ending index, exclusive.
 855      * @return     the unsigned {@code int} represented by the subsequence in
 856      *             the specified radix.
 857      * @throws     NullPointerException  if {@code s} is null.
 858      * @throws     IndexOutOfBoundsException  if {@code beginIndex} is
 859      *             negative, or if {@code beginIndex} is greater than
 860      *             {@code endIndex} or if {@code endIndex} is greater than
 861      *             {@code s.length()}.
 862      * @throws     NumberFormatException  if the {@code CharSequence} does not
 863      *             contain a parsable unsigned {@code int} in the specified
 864      *             {@code radix}, or if {@code radix} is either smaller than
 865      *             {@link java.lang.Character#MIN_RADIX} or larger than
 866      *             {@link java.lang.Character#MAX_RADIX}.
 867      * @since  1.9
 868      */
 869     static int parseUnsignedInt(CharSequence s, int radix, int beginIndex, int endIndex)
 870                 throws NumberFormatException {
 871         s = Objects.requireNonNull(s);
 872 
 873         if (beginIndex < 0 || beginIndex > endIndex || endIndex > s.length()) {
 874             throw new IndexOutOfBoundsException();
 875         }
 876         int start = beginIndex, len = endIndex - beginIndex;
 877 
 878         if (len > 0) {
 879             char firstChar = s.charAt(start);
 880             if (firstChar == '-') {
 881                 throw new
 882                     NumberFormatException(String.format("Illegal leading minus sign " +
 883                                                        "on unsigned string %s.", s));
 884             } else {
 885                 if (len <= 5 || // Integer.MAX_VALUE in Character.MAX_RADIX is 6 digits
 886                         (radix == 10 && len <= 9)) { // Integer.MAX_VALUE in base 10 is 10 digits
 887                     return parseInt(s, radix, start, start + len);
 888                 } else {
 889                     long ell = Long.parseLong(s, radix, start, start + len);
 890                     if ((ell & 0xffff_ffff_0000_0000L) == 0) {
 891                         return (int) ell;
 892                     } else {
 893                         throw new
 894                             NumberFormatException(String.format("String value %s exceeds " +
 895                                                                 "range of unsigned int.", s));
 896                     }
 897                 }
 898             }
 899         } else {
 900             throw new NumberFormatException("");
 901         }
 902     }
 903 
 904     /**
 905      * Parses the string argument as an unsigned decimal integer. The
 906      * characters in the string must all be decimal digits, except
 907      * that the first character may be an an ASCII plus sign {@code
 908      * '+'} ({@code '\u005Cu002B'}). The resulting integer value
 909      * is returned, exactly as if the argument and the radix 10 were
 910      * given as arguments to the {@link
 911      * #parseUnsignedInt(java.lang.String, int)} method.
 912      *
 913      * @param s   a {@code String} containing the unsigned {@code int}
 914      *            representation to be parsed
 915      * @return    the unsigned integer value represented by the argument in decimal.
 916      * @throws    NumberFormatException  if the string does not contain a
 917      *            parsable unsigned integer.
 918      * @since 1.8
 919      */
 920     public static int parseUnsignedInt(String s) throws NumberFormatException {