From 750e57765b10d0f072eff68274047daa1c2040ae Mon Sep 17 00:00:00 2001 From: Gilles Dubochet Date: Mon, 30 Apr 2007 18:14:11 +0000 Subject: Changed Scala's value boxing scheme to be compa... MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed Scala's value boxing scheme to be compatible with java's wrapping classes. - “Definitions” redefines what the boxed correspondants of value types are. - “GenJVM” uses the new (un)boxing methods defined in “BoxesUtility” (MSIL not updated yet). - “GenICode” special cases the “equals” method (to that of “Comparator”) in some cases to deal with Java's silly definition of equality on wrapped values. - Various other fixes (in erasure to deal properly with boxing of labelled expressions, big integers, etc.). --- src/library/scala/BigInt.scala | 13 +- src/library/scala/runtime/BoxedAnyArray.scala | 150 +++++++++---------- src/library/scala/runtime/BoxedBooleanArray.scala | 4 +- src/library/scala/runtime/BoxedByteArray.scala | 4 +- src/library/scala/runtime/BoxedCharArray.scala | 4 +- src/library/scala/runtime/BoxedDoubleArray.scala | 4 +- src/library/scala/runtime/BoxedFloatArray.scala | 4 +- src/library/scala/runtime/BoxedIntArray.scala | 4 +- src/library/scala/runtime/BoxedLongArray.scala | 4 +- src/library/scala/runtime/BoxedShortArray.scala | 4 +- src/library/scala/runtime/BoxesUtility.java | 167 ++++++++++++++++++++++ src/library/scala/runtime/Comparator.java | 40 ++++++ 12 files changed, 305 insertions(+), 97 deletions(-) create mode 100644 src/library/scala/runtime/BoxesUtility.java create mode 100644 src/library/scala/runtime/Comparator.java (limited to 'src/library') diff --git a/src/library/scala/BigInt.scala b/src/library/scala/BigInt.scala index 9e98ec5a3e..bcdff55261 100644 --- a/src/library/scala/BigInt.scala +++ b/src/library/scala/BigInt.scala @@ -115,7 +115,7 @@ object BigInt { * @version 1.0, 15/07/2003 */ @serializable -class BigInt(val bigInteger: BigInteger) extends runtime.BoxedNumber { +class BigInt(val bigInteger: BigInteger) extends java.lang.Number { /** Returns the hash code for this BigInt. */ override def hashCode(): Int = this.bigInteger.hashCode() @@ -123,9 +123,10 @@ class BigInt(val bigInteger: BigInteger) extends runtime.BoxedNumber { /** Compares this BigInt with the specified value for equality. */ override def equals (that: Any): boolean = that match { - case that: runtime.BoxedDouble => this.bigInteger.doubleValue == that.doubleValue - case that: runtime.BoxedFloat => this.bigInteger.floatValue == that.floatValue - case that: runtime.BoxedNumber => this equals BigInt(that.longValue) + case that: java.lang.Double => this.bigInteger.doubleValue == that.doubleValue + case that: java.lang.Float => this.bigInteger.floatValue == that.floatValue + case that: java.lang.Number => this equals BigInt(that.longValue) + case that: java.lang.Character => this equals BigInt(that.charValue.asInstanceOf[Int]) case _ => false } @@ -300,14 +301,14 @@ class BigInt(val bigInteger: BigInteger) extends runtime.BoxedNumber { * Note that this conversion can lose information about the overall magnitude of the * BigInt value as well as return a result with the opposite sign. */ - def byteValue = intValue.toByte + override def byteValue = intValue.toByte /** Converts this BigInt to a short. * If the BigInt is too big to fit in a byte, only the low-order 16 bits are returned. * Note that this conversion can lose information about the overall magnitude of the * BigInt value as well as return a result with the opposite sign. */ - def shortValue = intValue.toShort + override def shortValue = intValue.toShort /** Converts this BigInt to a char. * If the BigInt is too big to fit in a char, only the low-order 16 bits are returned. diff --git a/src/library/scala/runtime/BoxedAnyArray.scala b/src/library/scala/runtime/BoxedAnyArray.scala index 2c8711d763..d6093fe027 100644 --- a/src/library/scala/runtime/BoxedAnyArray.scala +++ b/src/library/scala/runtime/BoxedAnyArray.scala @@ -31,21 +31,21 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray { if (unboxed eq null) boxed(index); else if (elemClass eq classOf[Int]) - Int.box(unboxed.asInstanceOf[Array[Int]](index)) + BoxesUtility.boxToInteger(unboxed.asInstanceOf[Array[Int]](index)) else if (elemClass eq classOf[Double]) - Double.box(unboxed.asInstanceOf[Array[Double]](index)) + BoxesUtility.boxToDouble(unboxed.asInstanceOf[Array[Double]](index)) else if (elemClass eq classOf[Float]) - Float.box(unboxed.asInstanceOf[Array[Float]](index)) + BoxesUtility.boxToFloat(unboxed.asInstanceOf[Array[Float]](index)) else if (elemClass eq classOf[Long]) - Long.box(unboxed.asInstanceOf[Array[Long]](index)) + BoxesUtility.boxToLong(unboxed.asInstanceOf[Array[Long]](index)) else if (elemClass eq classOf[Char]) - Char.box(unboxed.asInstanceOf[Array[Char]](index)) + BoxesUtility.boxToCharacter(unboxed.asInstanceOf[Array[Char]](index)) else if (elemClass eq classOf[Byte]) - Byte.box(unboxed.asInstanceOf[Array[Byte]](index)) + BoxesUtility.boxToByte(unboxed.asInstanceOf[Array[Byte]](index)) else if (elemClass eq classOf[Short]) - Short.box(unboxed.asInstanceOf[Array[Short]](index)) + BoxesUtility.boxToShort(unboxed.asInstanceOf[Array[Short]](index)) else if (elemClass eq classOf[Boolean]) - Boolean.box(unboxed.asInstanceOf[Array[Boolean]](index)) + BoxesUtility.boxToBoolean(unboxed.asInstanceOf[Array[Boolean]](index)) else unboxed.asInstanceOf[Array[AnyRef]](index) } @@ -55,21 +55,21 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray { if (unboxed eq null) boxed(index) = elem else if (elemClass eq classOf[Int]) - unboxed.asInstanceOf[Array[Int]](index) = Int.unbox(elem) + unboxed.asInstanceOf[Array[Int]](index) = BoxesUtility.unboxToInt(elem) else if (elemClass eq classOf[Double]) - unboxed.asInstanceOf[Array[Double]](index) = Double.unbox(elem) + unboxed.asInstanceOf[Array[Double]](index) = BoxesUtility.unboxToDouble(elem) else if (elemClass eq classOf[Float]) - unboxed.asInstanceOf[Array[Float]](index) = Float.unbox(elem) + unboxed.asInstanceOf[Array[Float]](index) = BoxesUtility.unboxToFloat(elem) else if (elemClass eq classOf[Long]) - unboxed.asInstanceOf[Array[Long]](index) = Long.unbox(elem) + unboxed.asInstanceOf[Array[Long]](index) = BoxesUtility.unboxToLong(elem) else if (elemClass eq classOf[Char]) - unboxed.asInstanceOf[Array[Char]](index) = Char.unbox(elem) + unboxed.asInstanceOf[Array[Char]](index) = BoxesUtility.unboxToChar(elem) else if (elemClass eq classOf[Byte]) - unboxed.asInstanceOf[Array[Byte]](index) = Byte.unbox(elem) + unboxed.asInstanceOf[Array[Byte]](index) = BoxesUtility.unboxToByte(elem) else if (elemClass eq classOf[Short]) - unboxed.asInstanceOf[Array[Short]](index) = Short.unbox(elem) + unboxed.asInstanceOf[Array[Short]](index) = BoxesUtility.unboxToShort(elem) else if (elemClass eq classOf[Boolean]) - unboxed.asInstanceOf[Array[Boolean]](index) = Boolean.unbox(elem) + unboxed.asInstanceOf[Array[Boolean]](index) = BoxesUtility.unboxToBoolean(elem) else unboxed.asInstanceOf[Array[AnyRef]](index) = elem } @@ -89,75 +89,75 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray { if (unboxed eq null) { this.elemClass = elemClass; if (elemClass eq classOf[Int]) { - val newvalue = new Array[Int](length) - var i = 0 - while (i < length) { - newvalue(i) = Int.unbox(boxed(i)) - i = i + 1 - } - unboxed = newvalue + val newvalue = new Array[Int](length) + var i = 0 + while (i < length) { + newvalue(i) = BoxesUtility.unboxToInt(boxed(i)) + i = i + 1 + } + unboxed = newvalue } else if (elemClass eq classOf[Double]) { - val newvalue = new Array[Double](length) - var i = 0 - while (i < length) { - newvalue(i) = Double.unbox(boxed(i)) - i = i + 1 - } - unboxed = newvalue; + val newvalue = new Array[Double](length) + var i = 0 + while (i < length) { + newvalue(i) = BoxesUtility.unboxToDouble(boxed(i)) + i = i + 1 + } + unboxed = newvalue; } else if (elemClass eq classOf[Float]) { - val newvalue = new Array[Float](length) - var i = 0 - while (i < length) { - newvalue(i) = Float.unbox(boxed(i)) - i = i + 1 - } - unboxed = newvalue; + val newvalue = new Array[Float](length) + var i = 0 + while (i < length) { + newvalue(i) = BoxesUtility.unboxToFloat(boxed(i)) + i = i + 1 + } + unboxed = newvalue; } else if (elemClass eq classOf[Long]) { - val newvalue = new Array[Long](length) - var i = 0 - while (i < length) { - newvalue(i) = Long.unbox(boxed(i)) - i = i + 1 - } - unboxed = newvalue; + val newvalue = new Array[Long](length) + var i = 0 + while (i < length) { + newvalue(i) = BoxesUtility.unboxToLong(boxed(i)) + i = i + 1 + } + unboxed = newvalue; } else if (elemClass eq classOf[Char]) { - val newvalue = new Array[Char](length) - var i = 0 - while (i < length) { - newvalue(i) = Char.unbox(boxed(i)) - i = i + 1 - } - unboxed = newvalue + val newvalue = new Array[Char](length) + var i = 0 + while (i < length) { + newvalue(i) = BoxesUtility.unboxToChar(boxed(i)) + i = i + 1 + } + unboxed = newvalue } else if (elemClass eq classOf[Byte]) { - val newvalue = new Array[Byte](length) - var i = 0 - while (i < length) { - newvalue(i) = Byte.unbox(boxed(i)) - i = i + 1 - } - unboxed = newvalue; + val newvalue = new Array[Byte](length) + var i = 0 + while (i < length) { + newvalue(i) = BoxesUtility.unboxToByte(boxed(i)) + i = i + 1 + } + unboxed = newvalue; } else if (elemClass eq classOf[Short]) { - val newvalue = new Array[Short](length) - var i = 0 - while (i < length) { - newvalue(i) = Short.unbox(boxed(i)) - i = i + 1 - } - unboxed = newvalue; + val newvalue = new Array[Short](length) + var i = 0 + while (i < length) { + newvalue(i) = BoxesUtility.unboxToShort(boxed(i)) + i = i + 1 + } + unboxed = newvalue; } else if (elemClass eq classOf[Boolean]) { - val newvalue = new Array[Boolean](length) - var i = 0 - while (i < length) { - newvalue(i) = Boolean.unbox(boxed(i)) - i = i + 1 - } - unboxed = newvalue; + val newvalue = new Array[Boolean](length) + var i = 0 + while (i < length) { + newvalue(i) = BoxesUtility.unboxToBoolean(boxed(i)) + i = i + 1 + } + unboxed = newvalue; } else if (elemClass == boxed.getClass().getComponentType()) { // todo: replace with ScalaRunTime.AnyRef.class - unboxed = boxed + unboxed = boxed } else { - unboxed = Platform.createArray(elemClass, length); - Platform.arraycopy(boxed, 0, unboxed, 0, length); + unboxed = Platform.createArray(elemClass, length); + Platform.arraycopy(boxed, 0, unboxed, 0, length); } boxed = null } diff --git a/src/library/scala/runtime/BoxedBooleanArray.scala b/src/library/scala/runtime/BoxedBooleanArray.scala index 1f0567abad..e0ff708205 100644 --- a/src/library/scala/runtime/BoxedBooleanArray.scala +++ b/src/library/scala/runtime/BoxedBooleanArray.scala @@ -19,10 +19,10 @@ final class BoxedBooleanArray(val value: Array[Boolean]) extends BoxedArray { def length: Int = value.length - def apply(index: Int): Any = Boolean.box(value(index)) + def apply(index: Int): Any = BoxesUtility.boxToBoolean(value(index)) def update(index: Int, elem: Any): Unit = { - value(index) = Boolean.unbox(elem.asInstanceOf[AnyRef]) + value(index) = BoxesUtility.unboxToBoolean(elem.asInstanceOf[AnyRef]) } def unbox(elemTag: String): AnyRef = value diff --git a/src/library/scala/runtime/BoxedByteArray.scala b/src/library/scala/runtime/BoxedByteArray.scala index 753dbaea04..cf3d6bee6a 100644 --- a/src/library/scala/runtime/BoxedByteArray.scala +++ b/src/library/scala/runtime/BoxedByteArray.scala @@ -19,10 +19,10 @@ final class BoxedByteArray(val value: Array[Byte]) extends BoxedArray { def length: Int = value.length - def apply(index: Int): Any = Byte.box(value(index)) + def apply(index: Int): Any = BoxesUtility.boxToByte(value(index)) def update(index: Int, elem: Any): Unit = { - value(index) = Byte.unbox(elem.asInstanceOf[AnyRef]) + value(index) = BoxesUtility.unboxToByte(elem.asInstanceOf[AnyRef]) } def unbox(elemTag: String): AnyRef = value diff --git a/src/library/scala/runtime/BoxedCharArray.scala b/src/library/scala/runtime/BoxedCharArray.scala index adb14dda51..c13a31134a 100644 --- a/src/library/scala/runtime/BoxedCharArray.scala +++ b/src/library/scala/runtime/BoxedCharArray.scala @@ -19,10 +19,10 @@ final class BoxedCharArray(val value: Array[Char]) extends BoxedArray { def length: Int = value.length - def apply(index: Int): Any = Char.box(value(index)) + def apply(index: Int): Any = BoxesUtility.boxToCharacter(value(index)) def update(index: Int, elem: Any): Unit = { - value(index) = Char.unbox(elem.asInstanceOf[AnyRef]) + value(index) = BoxesUtility.unboxToChar(elem.asInstanceOf[AnyRef]) } def unbox(elemTag: String): AnyRef = value diff --git a/src/library/scala/runtime/BoxedDoubleArray.scala b/src/library/scala/runtime/BoxedDoubleArray.scala index 9a4564e439..08c3b6b843 100644 --- a/src/library/scala/runtime/BoxedDoubleArray.scala +++ b/src/library/scala/runtime/BoxedDoubleArray.scala @@ -19,10 +19,10 @@ final class BoxedDoubleArray(val value: Array[Double]) extends BoxedArray { def length: Int = value.length - def apply(index: Int): Any = Double.box(value(index)) + def apply(index: Int): Any = BoxesUtility.boxToDouble(value(index)) def update(index: Int, elem: Any): Unit = { - value(index) = Double.unbox(elem.asInstanceOf[AnyRef]) + value(index) = BoxesUtility.unboxToDouble(elem.asInstanceOf[AnyRef]) } def unbox(elemTag: String): AnyRef = value diff --git a/src/library/scala/runtime/BoxedFloatArray.scala b/src/library/scala/runtime/BoxedFloatArray.scala index 1b8ccb3797..13424f136b 100644 --- a/src/library/scala/runtime/BoxedFloatArray.scala +++ b/src/library/scala/runtime/BoxedFloatArray.scala @@ -19,10 +19,10 @@ final class BoxedFloatArray(val value: Array[Float]) extends BoxedArray { def length: Int = value.length - def apply(index: Int): Any = Float.box(value(index)) + def apply(index: Int): Any = BoxesUtility.boxToFloat(value(index)) def update(index: Int, elem: Any): Unit = { - value(index) = Float.unbox(elem.asInstanceOf[AnyRef]) + value(index) = BoxesUtility.unboxToFloat(elem.asInstanceOf[AnyRef]) } def unbox(elemTag: String): AnyRef = value diff --git a/src/library/scala/runtime/BoxedIntArray.scala b/src/library/scala/runtime/BoxedIntArray.scala index d2f5fd0371..a64f4fdb60 100644 --- a/src/library/scala/runtime/BoxedIntArray.scala +++ b/src/library/scala/runtime/BoxedIntArray.scala @@ -19,10 +19,10 @@ final class BoxedIntArray(val value: Array[Int]) extends BoxedArray { def length: Int = value.length - def apply(index: Int): Any = Int.box(value(index)) + def apply(index: Int): Any = BoxesUtility.boxToInteger(value(index)) def update(index: Int, elem: Any): Unit = { - value(index) = Int.unbox(elem.asInstanceOf[AnyRef]) + value(index) = BoxesUtility.unboxToInt(elem.asInstanceOf[AnyRef]) } def unbox(elemTag: String): AnyRef = value diff --git a/src/library/scala/runtime/BoxedLongArray.scala b/src/library/scala/runtime/BoxedLongArray.scala index 6accc84484..db4b266e1b 100644 --- a/src/library/scala/runtime/BoxedLongArray.scala +++ b/src/library/scala/runtime/BoxedLongArray.scala @@ -19,10 +19,10 @@ final class BoxedLongArray(val value: Array[Long]) extends BoxedArray { def length: Int = value.length - def apply(index: Int): Any = Long.box(value(index)) + def apply(index: Int): Any = BoxesUtility.boxToLong(value(index)) def update(index: Int, elem: Any): Unit = { - value(index) = Long.unbox(elem.asInstanceOf[AnyRef]) + value(index) = BoxesUtility.unboxToLong(elem.asInstanceOf[AnyRef]) } def unbox(elemTag: String): AnyRef = value diff --git a/src/library/scala/runtime/BoxedShortArray.scala b/src/library/scala/runtime/BoxedShortArray.scala index 161b7b921b..229ee46727 100644 --- a/src/library/scala/runtime/BoxedShortArray.scala +++ b/src/library/scala/runtime/BoxedShortArray.scala @@ -19,10 +19,10 @@ final class BoxedShortArray(val value: Array[Short]) extends BoxedArray { def length: Int = value.length - def apply(index: Int): Any = Short.box(value(index)) + def apply(index: Int): Any = BoxesUtility.boxToShort(value(index)) def update(index: Int, elem: Any): Unit = { - value(index) = Short.unbox(elem.asInstanceOf[AnyRef]) + value(index) = BoxesUtility.unboxToShort(elem.asInstanceOf[AnyRef]) } def unbox(elemTag: String): AnyRef = value diff --git a/src/library/scala/runtime/BoxesUtility.java b/src/library/scala/runtime/BoxesUtility.java new file mode 100644 index 0000000000..3edfef81f6 --- /dev/null +++ b/src/library/scala/runtime/BoxesUtility.java @@ -0,0 +1,167 @@ +package scala.runtime; + +public class BoxesUtility { + + private static int charLowBound = 0; + private static int charUpBound = 255; + private static Character[] charCache = new Character[charUpBound - charLowBound + 1]; + + private static int byteLowBound = -128; + private static int byteUpBound = 127; + private static Byte[] byteCache = new Byte[byteUpBound - byteLowBound + 1]; + + private static int shortLowBound = -128; + private static int shortUpBound = 127; + private static Short[] shortCache = new Short[shortUpBound - shortLowBound + 1]; + + private static int intLowBound = -128; + private static int intUpBound = 1024; + private static Integer[] intCache = new Integer[intUpBound - intLowBound + 1]; + + private static int longLowBound = -128; + private static int longUpBound = 1024; + private static Long[] longCache = new Long[longUpBound - longLowBound + 1]; + + static { + int idx = 0; + while (idx <= charUpBound - charLowBound) { + charCache[idx] = new Character((char)(idx + charLowBound)); + idx = idx + 1; + } + idx = 0; + while (idx <= byteUpBound - byteLowBound) { + byteCache[idx] = new Byte((byte)(idx + byteLowBound)); + idx = idx + 1; + } + idx = 0; + while (idx <= shortUpBound - shortLowBound) { + shortCache[idx] = new Short((short)(idx + shortLowBound)); + idx = idx + 1; + } + idx = 0; + while (idx <= intUpBound - intLowBound) { + intCache[idx] = new Integer((int)(idx + intLowBound)); + idx = idx + 1; + } + idx = 0; + while (idx <= longUpBound - longLowBound) { + longCache[idx] = new Long((long)(idx + longLowBound)); + idx = idx + 1; + } + } + + public static Boolean boxToBoolean(boolean b) { + return b ? Boolean.TRUE : Boolean.FALSE; + } + + public static Character boxToCharacter(char c) { + if (c >= charLowBound && c <= charUpBound) + return charCache[(int)c - charLowBound]; + else + return new Character(c); + } + + public static Byte boxToByte(byte b) { + if (b >= byteLowBound && b <= byteUpBound) + return byteCache[(int)b - byteLowBound]; + else + return new Byte(b); + } + + public static Short boxToShort(short s) { + if (s >= shortLowBound && s <= shortUpBound) + return shortCache[(int)s - shortLowBound]; + else + return new Short(s); + } + + public static Integer boxToInteger(int i) { + if (i >= intLowBound && i <= intUpBound) + return intCache[(int)i - intLowBound]; + else + return new Integer(i); + } + + public static Long boxToLong(long l) { + if (l >= longLowBound && l <= longUpBound) + return longCache[(int)l - longLowBound]; + else + return new Long(l); + } + + public static Float boxToFloat(float f) { + return new Float(f); + } + + public static Double boxToDouble(double d) { + return new Double(d); + } + + public static boolean unboxToBoolean(Object b) { + return b == null ? false : ((Boolean)b).booleanValue(); + } + + public static char unboxToChar(Object c) { + if (c == null) + return 0; + else if (c instanceof Character) + return ((Character)c).charValue(); + else + return ((char)((Number)c).intValue()); + } + + public static byte unboxToByte(Object b) { + if (b == null) + return 0; + else if (b instanceof Number) + return ((Number)b).byteValue(); + else + return ((byte)((Character)b).charValue()); + } + + public static short unboxToShort(Object s) { + if (s == null) + return 0; + else if (s instanceof Number) + return ((Number)s).shortValue(); + else + return ((short)((Character)s).charValue()); + } + + public static int unboxToInt(Object i) { + if (i == null) + return 0; + else if (i instanceof Number) + return ((Number)i).intValue(); + else + return ((int)((Character)i).charValue()); + } + + public static long unboxToLong(Object l) { + if (l == null) + return 0; + else if (l instanceof Number) + return ((Number)l).longValue(); + else + return ((long)((Character)l).charValue()); + } + + public static float unboxToFloat(Object f) { + if (f == null) + return 0.0f; + else if (f instanceof Number) + return ((Number)f).floatValue(); + else + return ((float)((Character)f).charValue()); + } + + public static double unboxToDouble(Object d) { + if (d == null) + return 0.0; + else if (d instanceof Number) + return ((Number)d).doubleValue(); + else + return ((double)((Character)d).charValue()); + } + +} diff --git a/src/library/scala/runtime/Comparator.java b/src/library/scala/runtime/Comparator.java new file mode 100644 index 0000000000..b090d5052e --- /dev/null +++ b/src/library/scala/runtime/Comparator.java @@ -0,0 +1,40 @@ +package scala.runtime; + +public class Comparator { + + /* A rich implementation of the equals method that overrides the default equals because Java's boxed primitives are + * utterly broken. This equals is inserted instead of a normal equals by the Scala compiler (in the icode phase, + * method genEqEqPrimitive) only when either side of the comparison is a subclass of AnyVal, of java.lang.Number, of + * java.lang.Character or is exactly Any or AnyRef. */ + public static boolean equals(Object a, Object b) { + if (a == null) + return b == null; + else if (a.equals(b)) + return true; + else if (a == b) + return true; + else if ((a instanceof Byte || a instanceof Short || a instanceof Integer) && b instanceof Number) + return ((Number)a).intValue() == ((Number)b).intValue(); + else if (a instanceof Number && (b instanceof Byte || b instanceof Short || b instanceof Integer)) + return ((Number)a).intValue() == ((Number)b).intValue(); + else if (a instanceof Long && b instanceof Number) + return ((Long)a).longValue() == ((Number)b).longValue(); + else if (a instanceof Number && b instanceof Long) + return ((Number)a).longValue() == ((Long)b).longValue(); + else if (a instanceof Float && b instanceof Number) + return ((Float)a).floatValue() == ((Number)b).floatValue(); + else if (a instanceof Number && b instanceof Float) + return ((Number)a).floatValue() == ((Float)b).floatValue(); + else if (a instanceof Number && b instanceof Number) + return ((Number)a).doubleValue() == ((Number)b).doubleValue(); + else if (a instanceof Number && b instanceof Character) + return ((Number)a).intValue() == ((Character)b).charValue(); + else if (a instanceof Character && b instanceof Number) + return ((Character)a).charValue() == ((Number)b).intValue(); + else if (a instanceof Character && b instanceof Character) + return ((Character)a).charValue() == ((Character)b).charValue(); + else + return false; + } + +} -- cgit v1.2.3