< prev index next >

src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java

Print this page

        

*** 117,134 **** /** JavaScript compliant conversion function from double to int32 */ public static final Call TO_INT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, double.class); /** JavaScript compliant conversion function from int to uint32 */ ! public static final Call TO_UINT32_I = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, int.class); /** JavaScript compliant conversion function from Object to uint32 */ public static final Call TO_UINT32 = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, Object.class); - /** JavaScript compliant conversion function from Object to long with type check */ - public static final Call TO_LONG_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toLongOptimistic", long.class, Object.class, int.class); - /** JavaScript compliant conversion function from number to uint32 */ public static final Call TO_UINT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, double.class); /** JavaScript compliant conversion function from number to String */ public static final Call TO_STRING_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toString", String.class, double.class); --- 117,134 ---- /** JavaScript compliant conversion function from double to int32 */ public static final Call TO_INT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, double.class); /** JavaScript compliant conversion function from int to uint32 */ ! public static final Call TO_UINT32_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32Optimistic", int.class, int.class, int.class); ! ! /** JavaScript compliant conversion function from int to uint32 */ ! public static final Call TO_UINT32_DOUBLE = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32Double", double.class, int.class); /** JavaScript compliant conversion function from Object to uint32 */ public static final Call TO_UINT32 = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, Object.class); /** JavaScript compliant conversion function from number to uint32 */ public static final Call TO_UINT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, double.class); /** JavaScript compliant conversion function from number to String */ public static final Call TO_STRING_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toString", String.class, double.class);
*** 170,209 **** public static final Call INCREMENT_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "incrementExact", int.class, int.class, int.class); /** Negate exact exact wrapper for potentially overflowing integer operations */ public static final Call NEGATE_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "negateExact", int.class, int.class, int.class); - /** Add exact wrapper for potentially overflowing long operations */ - public static final Call ADD_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "addExact", long.class, long.class, long.class, int.class); - - /** Sub exact wrapper for potentially overflowing long operations */ - public static final Call SUB_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "subExact", long.class, long.class, long.class, int.class); - - /** Multiply exact wrapper for potentially overflowing long operations */ - public static final Call MUL_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "mulExact", long.class, long.class, long.class, int.class); - - /** Div exact wrapper for potentially integer division that turns into float point */ - public static final Call DIV_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "divExact", long.class, long.class, long.class, int.class); - - /** Div zero wrapper for long division that handles (0/0) &gt;&gt;&gt; 0 == 0 */ - public static final Call DIV_ZERO_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "divZero", long.class, long.class, long.class); - - /** Mod zero wrapper for long division that handles (0%0) &gt;&gt;&gt; 0 == 0 */ - public static final Call REM_ZERO_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "remZero", long.class, long.class, long.class); - - /** Mod exact wrapper for potentially integer remainders that turns into float point */ - public static final Call REM_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "remExact", long.class, long.class, long.class, int.class); - - /** Decrement exact wrapper for potentially overflowing long operations */ - public static final Call DECREMENT_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "decrementExact", long.class, long.class, int.class); - - /** Increment exact wrapper for potentially overflowing long operations */ - public static final Call INCREMENT_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "incrementExact", long.class, long.class, int.class); - - /** Negate exact exact wrapper for potentially overflowing long operations */ - public static final Call NEGATE_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "negateExact", long.class, long.class, int.class); - /** Method handle to convert a JS Object to a Java array. */ public static final Call TO_JAVA_ARRAY = staticCall(JSTYPE_LOOKUP, JSType.class, "toJavaArray", Object.class, Object.class, Class.class); /** Method handle for void returns. */ public static final Call VOID_RETURN = staticCall(JSTYPE_LOOKUP, JSType.class, "voidReturn", void.class); --- 170,179 ----
*** 213,252 **** * in the dual--fields world */ private static final List<Type> ACCESSOR_TYPES = Collections.unmodifiableList( Arrays.asList( Type.INT, - Type.LONG, Type.NUMBER, Type.OBJECT)); /** table index for undefined type - hard coded so it can be used in switches at compile time */ public static final int TYPE_UNDEFINED_INDEX = -1; /** table index for integer type - hard coded so it can be used in switches at compile time */ public static final int TYPE_INT_INDEX = 0; //getAccessorTypeIndex(int.class); - /** table index for long type - hard coded so it can be used in switches at compile time */ - public static final int TYPE_LONG_INDEX = 1; //getAccessorTypeIndex(long.class); /** table index for double type - hard coded so it can be used in switches at compile time */ ! public static final int TYPE_DOUBLE_INDEX = 2; //getAccessorTypeIndex(double.class); /** table index for object type - hard coded so it can be used in switches at compile time */ ! public static final int TYPE_OBJECT_INDEX = 3; //getAccessorTypeIndex(Object.class); /** object conversion quickies with JS semantics - used for return value and parameter filter */ public static final List<MethodHandle> CONVERT_OBJECT = toUnmodifiableList( JSType.TO_INT32.methodHandle(), - JSType.TO_UINT32.methodHandle(), JSType.TO_NUMBER.methodHandle(), null ); /** * object conversion quickies with JS semantics - used for return value and parameter filter, optimistic * throws exception upon incompatible type (asking for a narrower one than the storage) */ public static final List<MethodHandle> CONVERT_OBJECT_OPTIMISTIC = toUnmodifiableList( JSType.TO_INT32_OPTIMISTIC.methodHandle(), - JSType.TO_LONG_OPTIMISTIC.methodHandle(), JSType.TO_NUMBER_OPTIMISTIC.methodHandle(), null ); /** The value of Undefined cast to an int32 */ --- 183,217 ---- * in the dual--fields world */ private static final List<Type> ACCESSOR_TYPES = Collections.unmodifiableList( Arrays.asList( Type.INT, Type.NUMBER, Type.OBJECT)); /** table index for undefined type - hard coded so it can be used in switches at compile time */ public static final int TYPE_UNDEFINED_INDEX = -1; /** table index for integer type - hard coded so it can be used in switches at compile time */ public static final int TYPE_INT_INDEX = 0; //getAccessorTypeIndex(int.class); /** table index for double type - hard coded so it can be used in switches at compile time */ ! public static final int TYPE_DOUBLE_INDEX = 1; //getAccessorTypeIndex(double.class); /** table index for object type - hard coded so it can be used in switches at compile time */ ! public static final int TYPE_OBJECT_INDEX = 2; //getAccessorTypeIndex(Object.class); /** object conversion quickies with JS semantics - used for return value and parameter filter */ public static final List<MethodHandle> CONVERT_OBJECT = toUnmodifiableList( JSType.TO_INT32.methodHandle(), JSType.TO_NUMBER.methodHandle(), null ); /** * object conversion quickies with JS semantics - used for return value and parameter filter, optimistic * throws exception upon incompatible type (asking for a narrower one than the storage) */ public static final List<MethodHandle> CONVERT_OBJECT_OPTIMISTIC = toUnmodifiableList( JSType.TO_INT32_OPTIMISTIC.methodHandle(), JSType.TO_NUMBER_OPTIMISTIC.methodHandle(), null ); /** The value of Undefined cast to an int32 */
*** 254,270 **** /** The value of Undefined cast to a long */ public static final long UNDEFINED_LONG = 0L; /** The value of Undefined cast to a double */ public static final double UNDEFINED_DOUBLE = Double.NaN; /** * Method handles for getters that return undefined coerced * to the appropriate type */ public static final List<MethodHandle> GET_UNDEFINED = toUnmodifiableList( MH.constant(int.class, UNDEFINED_INT), - MH.constant(long.class, UNDEFINED_LONG), MH.constant(double.class, UNDEFINED_DOUBLE), MH.constant(Object.class, Undefined.getUndefined()) ); private static final double INT32_LIMIT = 4294967296.0; --- 219,238 ---- /** The value of Undefined cast to a long */ public static final long UNDEFINED_LONG = 0L; /** The value of Undefined cast to a double */ public static final double UNDEFINED_DOUBLE = Double.NaN; + // Minimum and maximum range between which every long value can be precisely represented as a double. + private static final long MAX_PRECISE_DOUBLE = 1L << 53; + private static final long MIN_PRECISE_DOUBLE = -MAX_PRECISE_DOUBLE; + /** * Method handles for getters that return undefined coerced * to the appropriate type */ public static final List<MethodHandle> GET_UNDEFINED = toUnmodifiableList( MH.constant(int.class, UNDEFINED_INT), MH.constant(double.class, UNDEFINED_DOUBLE), MH.constant(Object.class, Undefined.getUndefined()) ); private static final double INT32_LIMIT = 4294967296.0;
*** 426,468 **** return false; } /** * Returns true if double number can be represented as a long. Note that it returns true for negative ! * zero. If you need to exclude negative zero, use {@link #isStrictlyRepresentableAsLong(double)}. * * @param number a double to inspect * @return true for long representable doubles */ public static boolean isRepresentableAsLong(final double number) { return (long)number == number; } /** ! * Returns true if double number can be represented as a long. Note that it returns false for negative ! * zero. If you don't need to distinguish negative zero, use {@link #isRepresentableAsLong(double)}. ! * ! * @param number a double to inspect ! * ! * @return true for long representable doubles */ ! public static boolean isStrictlyRepresentableAsLong(final double number) { ! return isRepresentableAsLong(number) && isNotNegativeZero(number); ! } ! ! /** ! * Returns true if Object can be represented as a long ! * ! * @param obj an object to inspect ! * ! * @return true for long representable objects ! */ ! public static boolean isRepresentableAsLong(final Object obj) { ! if (obj instanceof Number) { ! return isRepresentableAsLong(((Number)obj).doubleValue()); ! } ! return false; } /** * Returns true if the number is not the negative zero ({@code -0.0d}). * @param number the number to test --- 394,419 ---- return false; } /** * Returns true if double number can be represented as a long. Note that it returns true for negative ! * zero. * * @param number a double to inspect * @return true for long representable doubles */ public static boolean isRepresentableAsLong(final double number) { return (long)number == number; } /** ! * Returns true if long number can be represented as double without loss of precision. ! * @param number a long number ! * @return true if the double representation does not lose precision */ ! public static boolean isRepresentableAsDouble(final long number) { ! return MAX_PRECISE_DOUBLE >= number && number >= MIN_PRECISE_DOUBLE; } /** * Returns true if the number is not the negative zero ({@code -0.0d}). * @param number the number to test
*** 648,673 **** } return toString(obj); } /** - * Check whether a string is representable as a JavaScript number - * - * @param str a string - * - * @return true if string can be represented as a number - */ - public static boolean isNumber(final String str) { - try { - Double.parseDouble(str); - return true; - } catch (final NumberFormatException e) { - return false; - } - } - - /** * Returns true if object represents a primitive JavaScript string value. * @param obj the object * @return true if the object represents a primitive JavaScript string value. */ public static boolean isString(final Object obj) { --- 599,608 ----
*** 1031,1069 **** public static long toLong(final double num) { return (long)num; } /** - * Optimistic long conversion - throws UnwarrantedOptimismException if double or Object - * - * @param obj object to convert - * @param programPoint program point - * @return long - */ - public static long toLongOptimistic(final Object obj, final int programPoint) { - if (obj != null) { - final Class<?> clz = obj.getClass(); - if (clz == Long.class || clz == Integer.class) { - return ((Number)obj).longValue(); - } - } - throw new UnwarrantedOptimismException(obj, programPoint); - } - - /** - * Object to int conversion that delegates to either {@link #toLong(Object)} or to - * {@link #toLongOptimistic(Object, int)} depending on whether the program point is valid or not. - * @param obj the object to convert - * @param programPoint the program point; can be invalid. - * @return the value converted to long - * @throws UnwarrantedOptimismException if the value can't be represented as long and the program point is valid. - */ - public static long toLongMaybeOptimistic(final Object obj, final int programPoint) { - return UnwarrantedOptimismException.isValid(programPoint) ? toLongOptimistic(obj, programPoint) : toLong(obj); - } - - /** * JavaScript compliant Object to int32 conversion * See ECMA 9.5 ToInt32 * * @param obj an object * @return an int32 --- 966,975 ----
*** 1096,1109 **** */ public static int toInt32MaybeOptimistic(final Object obj, final int programPoint) { return UnwarrantedOptimismException.isValid(programPoint) ? toInt32Optimistic(obj, programPoint) : toInt32(obj); } - // Minimum and maximum range between which every long value can be precisely represented as a double. - private static final long MAX_PRECISE_DOUBLE = 1L << 53; - private static final long MIN_PRECISE_DOUBLE = -MAX_PRECISE_DOUBLE; - /** * JavaScript compliant long to int32 conversion * * @param num a long * @return an int32 --- 1002,1011 ----
*** 1152,1161 **** --- 1054,1086 ---- public static long toUint32(final int num) { return num & MAX_UINT; } /** + * Optimistic JavaScript compliant int to uint32 conversion + * @param num an int + * @param pp the program point + * @return the uint32 value if it can be represented by an int + * @throws UnwarrantedOptimismException if uint32 value cannot be represented by an int + */ + public static int toUint32Optimistic(final int num, final int pp) { + if (num >= 0) { + return num; + } + throw new UnwarrantedOptimismException(toUint32Double(num), pp, Type.NUMBER); + } + + /** + * JavaScript compliant int to uint32 conversion with double return type + * @param num an int + * @return the uint32 value as double + */ + public static double toUint32Double(final int num) { + return (double) toUint32(num); + } + + /** * JavaScript compliant Object to uint16 conversion * ECMA 9.7 ToUint16: (Unsigned 16 Bit Integer) * * @param obj an object * @return a uint16
*** 1482,1511 **** */ public static int addExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException { try { return Math.addExact(x, y); } catch (final ArithmeticException e) { - throw new UnwarrantedOptimismException((long)x + (long)y, programPoint); - } - } - - /** - * Wrapper for addExact - * - * Catches ArithmeticException and rethrows as UnwarrantedOptimismException - * containing the result and the program point of the failure - * - * @param x first term - * @param y second term - * @param programPoint program point id - * @return the result - * @throws UnwarrantedOptimismException if overflow occurs - */ - public static long addExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException { - try { - return Math.addExact(x, y); - } catch (final ArithmeticException e) { throw new UnwarrantedOptimismException((double)x + (double)y, programPoint); } } /** --- 1407,1416 ----
*** 1522,1551 **** */ public static int subExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException { try { return Math.subtractExact(x, y); } catch (final ArithmeticException e) { - throw new UnwarrantedOptimismException((long)x - (long)y, programPoint); - } - } - - /** - * Wrapper for subExact - * - * Catches ArithmeticException and rethrows as UnwarrantedOptimismException - * containing the result and the program point of the failure - * - * @param x first term - * @param y second term - * @param programPoint program point id - * @return the result - * @throws UnwarrantedOptimismException if overflow occurs - */ - public static long subExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException { - try { - return Math.subtractExact(x, y); - } catch (final ArithmeticException e) { throw new UnwarrantedOptimismException((double)x - (double)y, programPoint); } } /** --- 1427,1436 ----
*** 1562,1591 **** */ public static int mulExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException { try { return Math.multiplyExact(x, y); } catch (final ArithmeticException e) { - throw new UnwarrantedOptimismException((long)x * (long)y, programPoint); - } - } - - /** - * Wrapper for mulExact - * - * Catches ArithmeticException and rethrows as UnwarrantedOptimismException - * containing the result and the program point of the failure - * - * @param x first term - * @param y second term - * @param programPoint program point id - * @return the result - * @throws UnwarrantedOptimismException if overflow occurs - */ - public static long mulExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException { - try { - return Math.multiplyExact(x, y); - } catch (final ArithmeticException e) { throw new UnwarrantedOptimismException((double)x * (double)y, programPoint); } } /** --- 1447,1456 ----
*** 1653,1727 **** throw new UnwarrantedOptimismException(Double.NaN, programPoint); } } /** - * Wrapper for divExact. Throws UnwarrantedOptimismException if the result of the division can't be represented as - * long. - * - * @param x first term - * @param y second term - * @param programPoint program point id - * @return the result - * @throws UnwarrantedOptimismException if the result of the division can't be represented as long. - */ - public static long divExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException { - final long res; - try { - res = x / y; - } catch (final ArithmeticException e) { - assert y == 0L; // Only div by zero anticipated - throw new UnwarrantedOptimismException(x > 0L ? Double.POSITIVE_INFINITY : x < 0L ? Double.NEGATIVE_INFINITY : Double.NaN, programPoint); - } - final long rem = x % y; - if (rem == 0L) { - return res; - } - throw new UnwarrantedOptimismException((double)x / (double)y, programPoint); - } - - /** - * Implements long division but allows {@code x / 0} to be represented as 0. Useful when division of two longs - * is coerced to long. - * @param x the dividend - * @param y the divisor - * @return the result - */ - public static long divZero(final long x, final long y) { - return y == 0L ? 0L : x / y; - } - - /** - * Implements long remainder but allows {@code x % 0} to be represented as 0. Useful when remainder of two longs - * is coerced to long. - * @param x the dividend - * @param y the divisor - * @return the remainder - */ - public static long remZero(final long x, final long y) { - return y == 0L ? 0L : x % y; - } - - /** - * Wrapper for modExact. Throws UnwarrantedOptimismException if the modulo can't be represented as int. - * - * @param x first term - * @param y second term - * @param programPoint program point id - * @return the result - * @throws UnwarrantedOptimismException if the modulo can't be represented as int. - */ - public static long remExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException { - try { - return x % y; - } catch (final ArithmeticException e) { - assert y == 0L; // Only mod by zero anticipated - throw new UnwarrantedOptimismException(Double.NaN, programPoint); - } - } - - /** * Wrapper for decrementExact * * Catches ArithmeticException and rethrows as UnwarrantedOptimismException * containing the result and the program point of the failure * --- 1518,1527 ----
*** 1732,1761 **** */ public static int decrementExact(final int x, final int programPoint) throws UnwarrantedOptimismException { try { return Math.decrementExact(x); } catch (final ArithmeticException e) { ! throw new UnwarrantedOptimismException((long)x - 1, programPoint); ! } ! } ! ! /** ! * Wrapper for decrementExact ! * ! * Catches ArithmeticException and rethrows as UnwarrantedOptimismException ! * containing the result and the program point of the failure ! * ! * @param x number to negate ! * @param programPoint program point id ! * @return the result ! * @throws UnwarrantedOptimismException if overflow occurs ! */ ! public static long decrementExact(final long x, final int programPoint) throws UnwarrantedOptimismException { ! try { ! return Math.decrementExact(x); ! } catch (final ArithmeticException e) { ! throw new UnwarrantedOptimismException((double)x - 1L, programPoint); } } /** * Wrapper for incrementExact --- 1532,1542 ---- */ public static int decrementExact(final int x, final int programPoint) throws UnwarrantedOptimismException { try { return Math.decrementExact(x); } catch (final ArithmeticException e) { ! throw new UnwarrantedOptimismException((double)x - 1, programPoint); } } /** * Wrapper for incrementExact
*** 1770,1799 **** */ public static int incrementExact(final int x, final int programPoint) throws UnwarrantedOptimismException { try { return Math.incrementExact(x); } catch (final ArithmeticException e) { ! throw new UnwarrantedOptimismException((long)x + 1, programPoint); ! } ! } ! ! /** ! * Wrapper for incrementExact ! * ! * Catches ArithmeticException and rethrows as UnwarrantedOptimismException ! * containing the result and the program point of the failure ! * ! * @param x the number to increment ! * @param programPoint program point id ! * @return the result ! * @throws UnwarrantedOptimismException if overflow occurs ! */ ! public static long incrementExact(final long x, final int programPoint) throws UnwarrantedOptimismException { ! try { ! return Math.incrementExact(x); ! } catch (final ArithmeticException e) { ! throw new UnwarrantedOptimismException((double)x + 1L, programPoint); } } /** * Wrapper for negateExact --- 1551,1561 ---- */ public static int incrementExact(final int x, final int programPoint) throws UnwarrantedOptimismException { try { return Math.incrementExact(x); } catch (final ArithmeticException e) { ! throw new UnwarrantedOptimismException((double)x + 1, programPoint); } } /** * Wrapper for negateExact
*** 1811,1842 **** if (x == 0) { throw new UnwarrantedOptimismException(-0.0, programPoint); } return Math.negateExact(x); } catch (final ArithmeticException e) { - throw new UnwarrantedOptimismException(-(long)x, programPoint); - } - } - - /** - * Wrapper for negateExact - * - * Catches ArithmeticException and rethrows as UnwarrantedOptimismException - * containing the result and the program point of the failure - * - * @param x the number to negate - * @param programPoint program point id - * @return the result - * @throws UnwarrantedOptimismException if overflow occurs - */ - public static long negateExact(final long x, final int programPoint) throws UnwarrantedOptimismException { - try { - if (x == 0L) { - throw new UnwarrantedOptimismException(-0.0, programPoint); - } - return Math.negateExact(x); - } catch (final ArithmeticException e) { throw new UnwarrantedOptimismException(-(double)x, programPoint); } } /** --- 1573,1582 ----
*** 1864,1875 **** public static int getAccessorTypeIndex(final Class<?> type) { if (type == null) { return TYPE_UNDEFINED_INDEX; } else if (type == int.class) { return TYPE_INT_INDEX; - } else if (type == long.class) { - return TYPE_LONG_INDEX; } else if (type == double.class) { return TYPE_DOUBLE_INDEX; } else if (!type.isPrimitive()) { return TYPE_OBJECT_INDEX; } --- 1604,1613 ----
*** 1970,1981 **** * @return the boxed type of clazz, or unchanged if not primitive */ public static Class<?> getBoxedClass(final Class<?> clazz) { if (clazz == int.class) { return Integer.class; - } else if (clazz == long.class) { - return Long.class; } else if (clazz == double.class) { return Double.class; } assert !clazz.isPrimitive(); return clazz; --- 1708,1717 ----
*** 1989,2000 **** */ public static MethodHandle unboxConstant(final Object o) { if (o != null) { if (o.getClass() == Integer.class) { return MH.constant(int.class, ((Integer)o)); - } else if (o.getClass() == Long.class) { - return MH.constant(long.class, ((Long)o)); } else if (o.getClass() == Double.class) { return MH.constant(double.class, ((Double)o)); } } return MH.constant(Object.class, o); --- 1725,1734 ----
*** 2008,2019 **** public static Class<?> unboxedFieldType(final Object o) { if (o == null) { return Object.class; } else if (o.getClass() == Integer.class) { return int.class; - } else if (o.getClass() == Long.class) { - return long.class; } else if (o.getClass() == Double.class) { return double.class; } else { return Object.class; } --- 1742,1751 ----
< prev index next >