@@ -518,11 +518,63 @@ public double optDouble(int index) {
518518 * @return The value.
519519 */
520520 public double optDouble (int index , double defaultValue ) {
521- try {
522- return this .getDouble (index );
523- } catch (Exception e ) {
521+ Object val = this .opt (index );
522+ if (JSONObject .NULL .equals (val )) {
524523 return defaultValue ;
525524 }
525+ if (val instanceof Number ){
526+ return ((Number ) val ).doubleValue ();
527+ }
528+ if (val instanceof String ) {
529+ try {
530+ return new BigDecimal ((String ) val ).doubleValue ();
531+ } catch (Exception e ) {
532+ return defaultValue ;
533+ }
534+ }
535+ return defaultValue ;
536+ }
537+
538+ /**
539+ * Get the optional double value associated with an index. NaN is returned
540+ * if there is no value for the index, or if the value is not a number and
541+ * cannot be converted to a number.
542+ *
543+ * @param index
544+ * The index must be between 0 and length() - 1.
545+ * @return The value.
546+ */
547+ public float optFloat (int index ) {
548+ return this .optFloat (index , Float .NaN );
549+ }
550+
551+ /**
552+ * Get the optional double value associated with an index. The defaultValue
553+ * is returned if there is no value for the index, or if the value is not a
554+ * number and cannot be converted to a number.
555+ *
556+ * @param index
557+ * subscript
558+ * @param defaultValue
559+ * The default value.
560+ * @return The value.
561+ */
562+ public float optFloat (int index , float defaultValue ) {
563+ Object val = this .opt (index );
564+ if (JSONObject .NULL .equals (val )) {
565+ return defaultValue ;
566+ }
567+ if (val instanceof Number ){
568+ return ((Number ) val ).floatValue ();
569+ }
570+ if (val instanceof String ) {
571+ try {
572+ return new BigDecimal ((String ) val ).floatValue ();
573+ } catch (Exception e ) {
574+ return defaultValue ;
575+ }
576+ }
577+ return defaultValue ;
526578 }
527579
528580 /**
@@ -550,11 +602,22 @@ public int optInt(int index) {
550602 * @return The value.
551603 */
552604 public int optInt (int index , int defaultValue ) {
553- try {
554- return this .getInt (index );
555- } catch (Exception e ) {
605+ Object val = this .opt (index );
606+ if (JSONObject .NULL .equals (val )) {
556607 return defaultValue ;
557608 }
609+ if (val instanceof Number ){
610+ return ((Number ) val ).intValue ();
611+ }
612+
613+ if (val instanceof String ) {
614+ try {
615+ return new BigDecimal (val .toString ()).intValue ();
616+ } catch (Exception e ) {
617+ return defaultValue ;
618+ }
619+ }
620+ return defaultValue ;
558621 }
559622
560623 /**
@@ -615,8 +678,25 @@ public <E extends Enum<E>> E optEnum(Class<E> clazz, int index, E defaultValue)
615678 * @return The value.
616679 */
617680 public BigInteger optBigInteger (int index , BigInteger defaultValue ) {
681+ Object val = this .opt (index );
682+ if (JSONObject .NULL .equals (val )) {
683+ return defaultValue ;
684+ }
685+ if (val instanceof BigInteger ){
686+ return (BigInteger ) val ;
687+ }
688+ if (val instanceof BigDecimal ){
689+ return ((BigDecimal ) val ).toBigInteger ();
690+ }
691+ if (val instanceof Double || val instanceof Float ){
692+ return new BigDecimal (((Number ) val ).doubleValue ()).toBigInteger ();
693+ }
694+ if (val instanceof Long || val instanceof Integer
695+ || val instanceof Short || val instanceof Byte ){
696+ return BigInteger .valueOf (((Number ) val ).longValue ());
697+ }
618698 try {
619- return this . getBigInteger ( index );
699+ return new BigDecimal ( val . toString ()). toBigInteger ( );
620700 } catch (Exception e ) {
621701 return defaultValue ;
622702 }
@@ -634,8 +714,25 @@ public BigInteger optBigInteger(int index, BigInteger defaultValue) {
634714 * @return The value.
635715 */
636716 public BigDecimal optBigDecimal (int index , BigDecimal defaultValue ) {
717+ Object val = this .opt (index );
718+ if (JSONObject .NULL .equals (val )) {
719+ return defaultValue ;
720+ }
721+ if (val instanceof BigDecimal ){
722+ return (BigDecimal ) val ;
723+ }
724+ if (val instanceof BigInteger ){
725+ return new BigDecimal ((BigInteger ) val );
726+ }
727+ if (val instanceof Double || val instanceof Float ){
728+ return new BigDecimal (((Number ) val ).doubleValue ());
729+ }
730+ if (val instanceof Long || val instanceof Integer
731+ || val instanceof Short || val instanceof Byte ){
732+ return new BigDecimal (((Number ) val ).longValue ());
733+ }
637734 try {
638- return this . getBigDecimal ( index );
735+ return new BigDecimal ( val . toString () );
639736 } catch (Exception e ) {
640737 return defaultValue ;
641738 }
@@ -693,11 +790,53 @@ public long optLong(int index) {
693790 * @return The value.
694791 */
695792 public long optLong (int index , long defaultValue ) {
696- try {
697- return this .getLong (index );
698- } catch (Exception e ) {
793+ Object val = this .opt (index );
794+ if (JSONObject .NULL .equals (val )) {
699795 return defaultValue ;
700796 }
797+ if (val instanceof Number ){
798+ return ((Number ) val ).longValue ();
799+ }
800+
801+ if (val instanceof String ) {
802+ try {
803+ return new BigDecimal (val .toString ()).longValue ();
804+ } catch (Exception e ) {
805+ return defaultValue ;
806+ }
807+ }
808+ return defaultValue ;
809+ }
810+
811+ /**
812+ * Get an optional {@link Number} value associated with a key, or the default if there
813+ * is no such key or if the value is not a number. If the value is a string,
814+ * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
815+ * would be used in cases where type coercion of the number value is unwanted.
816+ *
817+ * @param index
818+ * The index must be between 0 and length() - 1.
819+ * @param defaultValue
820+ * The default.
821+ * @return An object which is the value.
822+ */
823+ public Number optNumber (int index , Number defaultValue ) {
824+ Object val = this .opt (index );
825+ if (JSONObject .NULL .equals (val )) {
826+ return defaultValue ;
827+ }
828+ if (val instanceof Number ){
829+ return (Number ) val ;
830+ }
831+
832+ if (val instanceof String ) {
833+ try {
834+ return new BigDecimal (val .toString ());
835+ } catch (Exception e ) {
836+ return defaultValue ;
837+ }
838+ }
839+ return defaultValue ;
701840 }
702841
703842 /**
0 commit comments