boxesruntime.java

来自「JAVA 语言的函数式编程扩展」· Java 代码 · 共 846 行 · 第 1/3 页

JAVA
846
字号
/*                     __                                               *\**     ________ ___   / /  ___     Scala API                            ****    / __/ __// _ | / /  / _ |    (c) 2006-2007, LAMP/EPFL             ****  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **** /____/\___/_/ |_/____/_/ | |                                         ****                          |/                                          **\*                                                                      */// $Id: BoxesRunTime.java 14532 2008-04-07 12:23:22Z washburn $package scala.runtime;/** An object (static class) that defines methods used for creating,  * reverting, and calculating with, boxed values. There are four classes  * of methods in this object:  *   - High-performance value boxing methods that feed from a pre-  *     computed map of instances for the most common instanciations.  *   - Convenience unboxing methods returning default value on null.  *   - The generalised comparison method to be used when an object may  *     be a boxed value.  *   - Standard value operators for boxed number and quasi-number values.  *  * @author  Gilles Dubochet  * @author  Martin Odersky  * @contributor Stepan Koltsov  * @version 2.0 */public class BoxesRunTime {    private static final int CHAR = 0, BYTE = 1, SHORT = 2, INT = 3, LONG = 4, FLOAT = 5, DOUBLE = 6, OTHER = 7;        private static int typeCode(Object a) {        if (a instanceof Integer) return INT;        if (a instanceof Character) return CHAR;        if (a instanceof Long) return LONG;        if (a instanceof Double) return DOUBLE;        if (a instanceof Float) return FLOAT;        if (a instanceof Byte) return BYTE;        if (a instanceof Short) return SHORT;        return OTHER;    }        /* BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING */        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];        return new Character(c);     }        public static Byte boxToByte(byte b) {        if (b >= byteLowBound && b <= byteUpBound)            return byteCache[(int)b - byteLowBound];        return new Byte(b);     }        public static Short boxToShort(short s) {        if (s >= shortLowBound && s <= shortUpBound)            return shortCache[(int)s - shortLowBound];        return new Short(s);     }        public static Integer boxToInteger(int i) {        if (i >= intLowBound && i <= intUpBound)            return intCache[(int)i - intLowBound];        return new Integer(i);     }        public static Long boxToLong(long l) {        if (l >= longLowBound && l <= longUpBound)            return longCache[(int)l - longLowBound];        return new Long(l);    }        public static Float boxToFloat(float f) {        return new Float(f);    }        public static Double boxToDouble(double d) {        return new Double(d);    }        /* UNBOXING ... UNBOXING ... UNBOXING ... UNBOXING ... UNBOXING ... UNBOXING ... UNBOXING */        public static boolean unboxToBoolean(Object b) {        return b == null ? false : ((Boolean)b).booleanValue();    }        public static char unboxToChar(Object c) {        return c == null ? 0 : ((Character)c).charValue();    }        public static byte unboxToByte(Object b) {        return b == null ? 0 : ((Byte)b).byteValue();    }        public static short unboxToShort(Object s) {        return s == null ? 0 : ((Short)s).shortValue();    }    public static int unboxToInt(Object i) {        return i == null ? 0 : ((Integer)i).intValue();    }        public static long unboxToLong(Object l) {        return l == null ? 0 : ((Long)l).longValue();    }        public static float unboxToFloat(Object f) {        return f == null ? 0.0f : ((Float)f).floatValue();    }        public static double unboxToDouble(Object d) {        return d == null ? 0.0d : ((Double)d).doubleValue();    }        /*    public static boolean unboxToBoolean(Object b) {        if (b == null)          throw new ClassCastException("null is no Boolean value");        return ((Boolean)b).booleanValue();    }        public static char unboxToChar(Object c) {        if (c == null)          throw new ClassCastException("null is no Char value");        return ((Character)c).charValue();    }        public static byte unboxToByte(Object b) {        if (b == null)          throw new ClassCastException("null is no Byte value");        return ((Byte)b).byteValue();    }        public static short unboxToShort(Object s) {        if (s == null)          throw new ClassCastException("null is no Short value");        return ((Short)s).shortValue();    }    public static int unboxToInt(Object i) {        if (i == null)          throw new ClassCastException("null is no Int value");        return ((Integer)i).intValue();    }        public static long unboxToLong(Object l) {        if (l == null)          throw new ClassCastException("null is no Long value");        return ((Long)l).longValue();    }        public static float unboxToFloat(Object f) {        if (f == null)          throw new ClassCastException("null is no Float value");        return ((Float)f).floatValue();    }        public static double unboxToDouble(Object d) {        if (d == null)          throw new ClassCastException("null is no Double value");        return ((Double)d).doubleValue();    }    */        /* COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON */    /** A rich implementation of the <code>equals</code> 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 <code>genEqEqPrimitive</code>) only when either      * side of the comparison is a subclass of <code>AnyVal</code>, of      * <code>java.lang.Number</code>, of <code>java.lang.Character</code> or      * is exactly <code>Any</code> or <code>AnyRef</code>. */    public static boolean equals(Object a, Object b) {        if (a == null || b == null)            return a == b;        if (a.equals(b))            return true;        if (a instanceof Number || a instanceof Character || b instanceof Number || b instanceof Character) {            int acode = typeCode(a);            int bcode = typeCode(b);            int maxcode = (acode < bcode) ? bcode : acode;            if (maxcode <= INT) {                int aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).intValue();                int bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).intValue();                return aa == bb;            }            if (maxcode <= LONG) {                long aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).longValue();                long bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).longValue();                return aa == bb;            }            if (maxcode <= FLOAT) {                float aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).floatValue();                float bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).floatValue();                return aa == bb;            }            if (maxcode <= DOUBLE) {                double aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).doubleValue();                double bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).doubleValue();                return aa == bb;            }			return b.equals(a);        }        return false;    }        /* OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS */            /** arg1 + arg2 */    public static Object add(Object arg1, Object arg2) throws NoSuchMethodException {        int code1 = typeCode(arg1);        int code2 = typeCode(arg2);        int maxcode = (code1 < code2) ? code2 : code1;        if (maxcode <= INT) {            int val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).intValue();            int val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).intValue();            return boxToInteger(val1 + val2);        }        if (maxcode <= LONG) {            long val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).longValue();            long val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).longValue();            return boxToLong(val1 + val2);        }        if (maxcode <= FLOAT) {            float val1 = (code1 == CHAR) ? ((Character) arg1).charValue() : ((Number) arg1).floatValue();            float val2 = (code2 == CHAR) ? ((Character) arg2).charValue() : ((Number) arg2).floatValue();            return boxToFloat(val1 + val2);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?