View Javadoc

1   /*
2    $Id: InvokerHelper.java,v 1.57 2004/12/08 02:53:27 spullara Exp $
3   
4    Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5   
6    Redistribution and use of this software and associated documentation
7    ("Software"), with or without modification, are permitted provided
8    that the following conditions are met:
9   
10   1. Redistributions of source code must retain copyright
11      statements and notices.  Redistributions must also contain a
12      copy of this document.
13  
14   2. Redistributions in binary form must reproduce the
15      above copyright notice, this list of conditions and the
16      following disclaimer in the documentation and/or other
17      materials provided with the distribution.
18  
19   3. The name "groovy" must not be used to endorse or promote
20      products derived from this Software without prior written
21      permission of The Codehaus.  For written permission,
22      please contact info@codehaus.org.
23  
24   4. Products derived from this Software may not be called "groovy"
25      nor may "groovy" appear in their names without prior written
26      permission of The Codehaus. "groovy" is a registered
27      trademark of The Codehaus.
28  
29   5. Due credit should be given to The Codehaus -
30      http://groovy.codehaus.org/
31  
32   THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
33   ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
34   NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
35   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
36   THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43   OF THE POSSIBILITY OF SUCH DAMAGE.
44  
45   */
46  package org.codehaus.groovy.runtime;
47  
48  import groovy.lang.*;
49  
50  import java.beans.Introspector;
51  import java.io.*;
52  import java.lang.reflect.Array;
53  import java.math.BigDecimal;
54  import java.math.BigInteger;
55  import java.util.*;
56  import java.util.regex.Matcher;
57  import java.util.regex.Pattern;
58  
59  /***
60   * A static helper class to make bytecode generation easier and act as a facade over the Invoker
61   *
62   * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
63   * @version $Revision: 1.57 $
64   */
65  public class InvokerHelper {
66      public static final Object[] EMPTY_ARGS = {
67      };
68  
69      private static final Object[] EMPTY_MAIN_ARGS = new Object[]{new String[0]};
70  
71      private static final Invoker singleton = new Invoker();
72  
73      private static final Integer ZERO = new Integer(0);
74      private static final Integer MINUS_ONE = new Integer(-1);
75      private static final Integer ONE = new Integer(1);
76  
77      public static MetaClass getMetaClass(Object object) {
78          return getInstance().getMetaClass(object);
79      }
80  
81      public static void removeClass(Class clazz) {
82          getInstance().removeMetaClass(clazz);
83          Introspector.flushFromCaches(clazz);
84      }
85  
86      public static Invoker getInstance() {
87          return singleton;
88      }
89  
90      public static Object invokeNoArgumentsMethod(Object object, String methodName) {
91          return getInstance().invokeMethod(object, methodName, EMPTY_ARGS);
92      }
93  
94      public static Object invokeMethod(Object object, String methodName, Object arguments) {
95          return getInstance().invokeMethod(object, methodName, arguments);
96      }
97  
98      public static Object invokeSuperMethod(Object object, String methodName, Object arguments) {
99          return getInstance().invokeSuperMethod(object, methodName, arguments);
100     }
101 
102     public static Object invokeMethodSafe(Object object, String methodName, Object arguments) {
103         if (object != null) {
104             return getInstance().invokeMethod(object, methodName, arguments);
105         }
106         return null;
107     }
108 
109     public static Object invokeStaticMethod(String type, String methodName, Object arguments) {
110         return getInstance().invokeStaticMethod(type, methodName, arguments);
111     }
112 
113     public static Object invokeStaticNoArgumentsMethod(String type, String methodName) {
114         return getInstance().invokeStaticMethod(type, methodName, EMPTY_ARGS);
115     }
116 
117     public static Object invokeConstructor(String type, Object arguments) {
118         return getInstance().invokeConstructor(type, arguments);
119     }
120 
121     public static Object invokeConstructorOf(Class type, Object arguments) {
122         return getInstance().invokeConstructorOf(type, arguments);
123     }
124 
125     public static Object invokeNoArgumentsConstructorOf(Class type) {
126         return getInstance().invokeConstructorOf(type, EMPTY_ARGS);
127     }
128 
129     public static Object invokeClosure(Object closure, Object arguments) {
130         return getInstance().invokeMethod(closure, "doCall", arguments);
131     }
132 
133     public static Iterator asIterator(Object collection) {
134         return getInstance().asIterator(collection);
135     }
136 
137     public static Collection asCollection(Object collection) {
138         return getInstance().asCollection(collection);
139     }
140 
141     public static List asList(Object args) {
142         return getInstance().asList(args);
143     }
144 
145     public static String toString(Object arguments) {
146         return getInstance().toString(arguments);
147     }
148 
149     public static String toTypeString(Object[] arguments) {
150         return getInstance().toTypeString(arguments);
151     }
152 
153     public static String inspect(Object self) {
154         return getInstance().inspect(self);
155     }
156 
157     public static Object getProperty(Object object, String property) {
158         return getInstance().getProperty(object, property);
159     }
160 
161     public static Object getPropertySafe(Object object, String property) {
162         if (object != null) {
163             return getInstance().getProperty(object, property);
164         }
165         return null;
166     }
167 
168     public static void setProperty(Object object, String property, Object newValue) {
169         getInstance().setProperty(object, property, newValue);
170     }
171 
172     /***
173      * This is so we don't have to reorder the stack when we call this method.
174      * At some point a better name might be in order.
175      */
176     public static void setProperty2(Object newValue, Object object, String property) {
177         getInstance().setProperty(object, property, newValue);
178     }
179 
180 
181     /***
182      * This is so we don't have to reorder the stack when we call this method.
183      * At some point a better name might be in order.
184      */
185     public static void setGroovyObjectProperty(Object newValue, GroovyObject object, String property) {
186         object.setProperty(property, newValue);
187     }
188 
189     public static Object getGroovyObjectProperty(GroovyObject object, String property) {
190         return object.getProperty(property);
191     }
192 
193 
194     /***
195      * This is so we don't have to reorder the stack when we call this method.
196      * At some point a better name might be in order.
197      */
198     public static void setPropertySafe2(Object newValue, Object object, String property) {
199         if (object != null) {
200             setProperty2(newValue, object, property);
201         }
202     }
203 
204     /***
205      * Provides a hook for type coercion of the given object to the required type
206      *
207      * @param type   of object to convert the given object to
208      * @param object the object to be converted
209      * @return the original object or a new converted value
210      */
211     public static Object asType(Object object, Class type) {
212         return getInstance().asType(object, type);
213     }
214 
215     public static boolean asBool(Object object) {
216         return getInstance().asBool(object);
217     }
218 
219     public static boolean notObject(Object object) {
220         return !asBool(object);
221     }
222 
223     public static boolean notBoolean(boolean bool) {
224         return !bool;
225     }
226 
227     public static Object negate(Object value) {
228         if (value instanceof Integer) {
229             Integer number = (Integer) value;
230             return integerValue(-number.intValue());
231         } else if (value instanceof Long) {
232             Long number = (Long) value;
233             return new Long(-number.longValue());
234         } else if (value instanceof BigInteger) {
235             return ((BigInteger) value).negate();
236         } else if (value instanceof BigDecimal) {
237             return ((BigDecimal) value).negate();
238         } else if (value instanceof Double) {
239             Double number = (Double) value;
240             return new Double(-number.doubleValue());
241         } else if (value instanceof Float) {
242             Float number = (Float) value;
243             return new Float(-number.floatValue());
244         } else {
245             throw new GroovyRuntimeException("Cannot negate type " + value.getClass().getName() + ", value " + value);
246         }
247     }
248 
249     public static boolean isCase(Object switchValue, Object caseExpression) {
250         return asBool(invokeMethod(caseExpression, "isCase", new Object[]{switchValue}));
251     }
252 
253     public static boolean compareIdentical(Object left, Object right) {
254         return left == right;
255     }
256 
257     public static boolean compareEqual(Object left, Object right) {
258         return getInstance().objectsEqual(left, right);
259     }
260 
261     public static Matcher findRegex(Object left, Object right) {
262         return getInstance().objectFindRegex(left, right);
263     }
264 
265     public static boolean matchRegex(Object left, Object right) {
266         return getInstance().objectMatchRegex(left, right);
267     }
268 
269     public static Pattern regexPattern(Object regex) {
270         return getInstance().regexPattern(regex);
271     }
272 
273     public static boolean compareNotEqual(Object left, Object right) {
274         return !getInstance().objectsEqual(left, right);
275     }
276 
277     public static boolean compareLessThan(Object left, Object right) {
278         return getInstance().compareTo(left, right) < 0;
279     }
280 
281     public static boolean compareLessThanEqual(Object left, Object right) {
282         return getInstance().compareTo(left, right) <= 0;
283     }
284 
285     public static boolean compareGreaterThan(Object left, Object right) {
286         return getInstance().compareTo(left, right) > 0;
287     }
288 
289     public static boolean compareGreaterThanEqual(Object left, Object right) {
290         return getInstance().compareTo(left, right) >= 0;
291     }
292 
293     public static Integer compareTo(Object left, Object right) {
294         int answer = getInstance().compareTo(left, right);
295         if (answer == 0) {
296             return ZERO;
297         } else {
298             return answer > 0 ? ONE : MINUS_ONE;
299         }
300     }
301 
302     public static Tuple createTuple(Object[] array) {
303         return new Tuple(array);
304     }
305 
306     public static List createList(Object[] values) {
307         ArrayList answer = new ArrayList(values.length);
308         for (int i = 0; i < values.length; i++) {
309             answer.add(values[i]);
310         }
311         return answer;
312     }
313 
314     public static Map createMap(Object[] values) {
315         Map answer = new HashMap(values.length / 2);
316         int i = 0;
317         while (i < values.length) {
318             answer.put(values[i++], values[i++]);
319         }
320         return answer;
321     }
322 
323     public static List createRange(Object from, Object to, boolean inclusive) {
324         if (!inclusive) {
325             if (compareGreaterThan(from, to)) {
326                 to = invokeMethod(to, "next", EMPTY_ARGS);
327             } else {
328                 to = invokeMethod(to, "previous", EMPTY_ARGS);
329             }
330         }
331         if (from instanceof Integer && to instanceof Integer) {
332             return new IntRange(asInt(from), asInt(to));
333         } else {
334             return new ObjectRange((Comparable) from, (Comparable) to);
335         }
336     }
337 
338     public static int asInt(Object value) {
339         return getInstance().asInt(value);
340     }
341 
342     public static void assertFailed(Object expression, Object message) {
343         if (message == null || "".equals(message)) {
344             throw new AssertionError("Expression: " + expression);
345         } else {
346             throw new AssertionError("" + message + ". Expression: " + expression);
347         }
348     }
349 
350     public static Object runScript(Class scriptClass, String[] args) {
351         Binding context = new Binding(args);
352         Script script = createScript(scriptClass, context);
353         return invokeMethod(script, "run", EMPTY_ARGS);
354     }
355 
356     public static Script createScript(Class scriptClass, Binding context) {
357         try {
358             final GroovyObject object = (GroovyObject) scriptClass.newInstance();
359             Script script = null;
360             if (object instanceof Script) {
361                 script = (Script) object;
362             } else {
363                 // it could just be a class, so lets wrap it in a Script wrapper
364                 // though the bindings will be ignored
365                 script = new Script() {
366                     public Object run() {
367                         object.invokeMethod("main", EMPTY_MAIN_ARGS);
368                         return null;
369                     }
370                 };
371                 setProperties(object, context.getVariables());
372             }
373             script.setBinding(context);
374             return script;
375         } catch (Exception e) {
376             throw new GroovyRuntimeException("Failed to create Script instance for class: " + scriptClass + ". Reason: " + e,
377                     e);
378         }
379     }
380 
381     /***
382      * Sets the properties on the given object
383      *
384      * @param object
385      * @param map
386      */
387     public static void setProperties(Object object, Map map) {
388         getMetaClass(object).setProperties(object, map);
389     }
390 
391     public static String getVersion() {
392         String version = null;
393         Package p = Package.getPackage("groovy.lang");
394         if (p != null) {
395             version = p.getImplementationVersion();
396         }
397         if (version == null) {
398             version = "";
399         }
400         return version;
401     }
402 
403     /***
404      * Allows conversion of arrays into a mutable List
405      *
406      * @return the array as a List
407      */
408     protected static List primitiveArrayToList(Object array) {
409         int size = Array.getLength(array);
410         List list = new ArrayList(size);
411         for (int i = 0; i < size; i++) {
412             list.add(Array.get(array, i));
413         }
414         return list;
415     }
416 
417     /***
418      * Writes the given object to the given stream
419      */
420     public static void write(Writer out, Object object) throws IOException {
421         if (object instanceof String) {
422             out.write((String) object);
423         } else if (object instanceof Writable) {
424             Writable writable = (Writable) object;
425             writable.writeTo(out);
426         } else if (object instanceof InputStream || object instanceof Reader) {
427             // Copy stream to stream
428             Reader reader;
429             if (object instanceof InputStream) {
430                 reader = new InputStreamReader((InputStream) object);
431             } else {
432                 reader = (Reader) object;
433             }
434             char[] chars = new char[8192];
435             int i;
436             while ((i = reader.read(chars)) != -1) {
437                 out.write(chars, 0, i);
438             }
439             reader.close();
440         } else {
441             out.write(toString(object));
442         }
443     }
444 
445     public static Object box(boolean value) {
446         return value ? Boolean.TRUE : Boolean.FALSE;
447     }
448 
449     public static Object box(byte value) {
450         return new Byte(value);
451     }
452 
453     public static Object box(char value) {
454         return new Character(value);
455     }
456 
457     public static Object box(short value) {
458         return new Short(value);
459     }
460 
461     public static Object box(int value) {
462         return integerValue(value);
463     }
464 
465     public static Object box(long value) {
466         return new Long(value);
467     }
468 
469     public static Object box(float value) {
470         return new Float(value);
471     }
472 
473     public static Object box(double value) {
474         return new Double(value);
475     }
476 
477     public static byte byteUnbox(Object value) {
478         Number n = (Number) asType(value, Byte.class);
479         return n.byteValue();
480     }
481 
482     public static char charUnbox(Object value) {
483         Character n = (Character) asType(value, Character.class);
484         return n.charValue();
485     }
486 
487     public static short shortUnbox(Object value) {
488         Number n = (Number) asType(value, Short.class);
489         return n.shortValue();
490     }
491 
492     public static int intUnbox(Object value) {
493         Number n = (Number) asType(value, Integer.class);
494         return n.intValue();
495     }
496 
497     public static boolean booleanUnbox(Object value) {
498         Boolean n = (Boolean) asType(value, Boolean.class);
499         return n.booleanValue();
500     }
501 
502     public static long longUnbox(Object value) {
503         Number n = (Number) asType(value, Long.class);
504         return n.longValue();
505     }
506 
507     public static float floatUnbox(Object value) {
508         Number n = (Number) asType(value, Float.class);
509         return n.floatValue();
510     }
511 
512     public static double doubleUnbox(Object value) {
513         Number n = (Number) asType(value, Double.class);
514         return n.doubleValue();
515     }
516 
517     /***
518      * @param a    array of primitives
519      * @param type component type of the array
520      * @return
521      */
522     public static Object[] convertPrimitiveArray(Object a, Class type) {
523 //        System.out.println("a.getClass() = " + a.getClass());
524         Object[] ans = null;
525         String elemType = type.getName();
526         if (elemType.equals("int")) {
527             // conservative coding
528             if (a.getClass().getName().equals("[Ljava.lang.Integer;")) {
529                 ans = (Integer[]) a;
530             } else {
531                 int[] ia = (int[]) a;
532                 ans = new Integer[ia.length];
533                 for (int i = 0; i < ia.length; i++) {
534                     int e = ia[i];
535                     ans[i] = integerValue(e);
536                 }
537             }
538         } else if (elemType.equals("char")) {
539             if (a.getClass().getName().equals("[Ljava.lang.Character;")) {
540                 ans = (Character[]) a;
541             } else {
542                 char[] ia = (char[]) a;
543                 ans = new Character[ia.length];
544                 for (int i = 0; i < ia.length; i++) {
545                     char e = ia[i];
546                     ans[i] = new Character(e);
547                 }
548             }
549         } else if (elemType.equals("boolean")) {
550             if (a.getClass().getName().equals("[Ljava.lang.Boolean;")) {
551                 ans = (Boolean[]) a;
552             } else {
553                 boolean[] ia = (boolean[]) a;
554                 ans = new Boolean[ia.length];
555                 for (int i = 0; i < ia.length; i++) {
556                     boolean e = ia[i];
557                     ans[i] = new Boolean(e);
558                 }
559             }
560         } else if (elemType.equals("byte")) {
561             if (a.getClass().getName().equals("[Ljava.lang.Byte;")) {
562                 ans = (Byte[]) a;
563             } else {
564                 byte[] ia = (byte[]) a;
565                 ans = new Byte[ia.length];
566                 for (int i = 0; i < ia.length; i++) {
567                     byte e = ia[i];
568                     ans[i] = new Byte(e);
569                 }
570             }
571         } else if (elemType.equals("short")) {
572             if (a.getClass().getName().equals("[Ljava.lang.Short;")) {
573                 ans = (Short[]) a;
574             } else {
575                 short[] ia = (short[]) a;
576                 ans = new Short[ia.length];
577                 for (int i = 0; i < ia.length; i++) {
578                     short e = ia[i];
579                     ans[i] = new Short(e);
580                 }
581             }
582         } else if (elemType.equals("float")) {
583             if (a.getClass().getName().equals("[Ljava.lang.Float;")) {
584                 ans = (Float[]) a;
585             } else {
586                 float[] ia = (float[]) a;
587                 ans = new Float[ia.length];
588                 for (int i = 0; i < ia.length; i++) {
589                     float e = ia[i];
590                     ans[i] = new Float(e);
591                 }
592             }
593         } else if (elemType.equals("long")) {
594             if (a.getClass().getName().equals("[Ljava.lang.Long;")) {
595                 ans = (Long[]) a;
596             } else {
597                 long[] ia = (long[]) a;
598                 ans = new Long[ia.length];
599                 for (int i = 0; i < ia.length; i++) {
600                     long e = ia[i];
601                     ans[i] = new Long(e);
602                 }
603             }
604         } else if (elemType.equals("double")) {
605             if (a.getClass().getName().equals("[Ljava.lang.Double;")) {
606                 ans = (Double[]) a;
607             } else {
608                 double[] ia = (double[]) a;
609                 ans = new Double[ia.length];
610                 for (int i = 0; i < ia.length; i++) {
611                     double e = ia[i];
612                     ans[i] = new Double(e);
613                 }
614             }
615         }
616         return ans;
617     }
618 
619     public static int[] convertToIntArray(Object a) {
620         int[] ans = null;
621 
622         // conservative coding
623         if (a.getClass().getName().equals("[I")) {
624             ans = (int[]) a;
625         } else {
626             Object[] ia = (Object[]) a;
627             ans = new int[ia.length];
628             for (int i = 0; i < ia.length; i++) {
629                 ans[i] = ((Number) ia[i]).intValue();
630             }
631         }
632         return ans;
633     }
634 
635     public static boolean[] convertToBooleanArray(Object a) {
636         boolean[] ans = null;
637 
638         // conservative coding
639         if (a.getClass().getName().equals("[Z")) {
640             ans = (boolean[]) a;
641         } else {
642             Object[] ia = (Object[]) a;
643             ans = new boolean[ia.length];
644             for (int i = 0; i < ia.length; i++) {
645                 ans[i] = ((Boolean) ia[i]).booleanValue();
646             }
647         }
648         return ans;
649     }
650 
651     public static byte[] convertToByteArray(Object a) {
652         byte[] ans = null;
653 
654         // conservative coding
655         if (a.getClass().getName().equals("[B")) {
656             ans = (byte[]) a;
657         } else {
658             Object[] ia = (Object[]) a;
659             ans = new byte[ia.length];
660             for (int i = 0; i < ia.length; i++) {
661                 ans[i] = ((Number) ia[i]).byteValue();
662             }
663         }
664         return ans;
665     }
666 
667     public static short[] convertToShortArray(Object a) {
668         short[] ans = null;
669 
670         // conservative coding
671         if (a.getClass().getName().equals("[S")) {
672             ans = (short[]) a;
673         } else {
674             Object[] ia = (Object[]) a;
675             ans = new short[ia.length];
676             for (int i = 0; i < ia.length; i++) {
677                 ans[i] = ((Number) ia[i]).shortValue();
678             }
679         }
680         return ans;
681     }
682 
683     public static char[] convertToCharArray(Object a) {
684         char[] ans = null;
685 
686         // conservative coding
687         if (a.getClass().getName().equals("[C")) {
688             ans = (char[]) a;
689         } else {
690             Object[] ia = (Object[]) a;
691             ans = new char[ia.length];
692             for (int i = 0; i < ia.length; i++) {
693                 ans[i] = ((Character) ia[i]).charValue();
694             }
695         }
696         return ans;
697     }
698 
699     public static long[] convertToLongArray(Object a) {
700         long[] ans = null;
701 
702         // conservative coding
703         if (a.getClass().getName().equals("[J")) {
704             ans = (long[]) a;
705         } else {
706             Object[] ia = (Object[]) a;
707             ans = new long[ia.length];
708             for (int i = 0; i < ia.length; i++) {
709                 ans[i] = ((Number) ia[i]).longValue();
710             }
711         }
712         return ans;
713     }
714 
715     public static float[] convertToFloatArray(Object a) {
716         float[] ans = null;
717 
718         // conservative coding
719         if (a.getClass().getName().equals("[F")) {
720             ans = (float[]) a;
721         } else {
722             Object[] ia = (Object[]) a;
723             ans = new float[ia.length];
724             for (int i = 0; i < ia.length; i++) {
725                 ans[i] = ((Number) ia[i]).floatValue();
726             }
727         }
728         return ans;
729     }
730 
731     public static double[] convertToDoubleArray(Object a) {
732         double[] ans = null;
733 
734         // conservative coding
735         if (a.getClass().getName().equals("[D")) {
736             ans = (double[]) a;
737         } else {
738             Object[] ia = (Object[]) a;
739             ans = new double[ia.length];
740             for (int i = 0; i < ia.length; i++) {
741                 ans[i] = ((Number) ia[i]).doubleValue();
742             }
743         }
744         return ans;
745     }
746 
747     public static Object convertToPrimitiveArray(Object a, Class type) {
748         if (type == Byte.TYPE)
749             return convertToByteArray(a);
750         if (type == Boolean.TYPE)
751             return convertToBooleanArray(a);
752         if (type == Short.TYPE)
753             return convertToShortArray(a);
754         if (type == Character.TYPE)
755             return convertToCharArray(a);
756         if (type == Integer.TYPE)
757             return convertToIntArray(a);
758         if (type == Long.TYPE)
759             return convertToLongArray(a);
760         if (type == Float.TYPE)
761             return convertToFloatArray(a);
762         if (type == Double.TYPE)
763             return convertToDoubleArray(a);
764         else
765             return a;
766     }
767 
768     /***
769      * get the Integer object from an int. Cached version is used for small ints.
770      *
771      * @param v
772      * @return
773      */
774     public static Integer integerValue(int v) {
775         int index = v + INT_CACHE_OFFSET;
776         if (index >= 0 && index < INT_CACHE_LEN) {
777             return SMALL_INTEGERS[index];
778         } else {
779             return new Integer(v);
780         }
781     }
782 
783     private static Integer[] SMALL_INTEGERS;
784     private static int INT_CACHE_OFFSET = 128, INT_CACHE_LEN = 256;
785 
786     static {
787         SMALL_INTEGERS = new Integer[INT_CACHE_LEN];
788         for (int i = 0; i < SMALL_INTEGERS.length; i++) {
789             SMALL_INTEGERS[i] = new Integer(i - INT_CACHE_OFFSET);
790         }
791     }
792 }