View Javadoc
1   package org.djutils.primitives;
2   
3   /**
4    * The Primitive class is a utility class to deal with primitives. Besides widening and unwidening this class casts and parses
5    * UTF8 strings into appropriate primitive classes.
6    * <p>
7    * Copyright (c) 2002-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
8    * for project information <a href="https://djutils.org" target="_blank"> https://djutils.org</a>. The DJUTILS project is
9    * distributed under a three-clause BSD-style license, which can be found at
10   * <a href="https://djutils.org/docs/license.html" target="_blank"> https://djutils.org/docs/license.html</a>.
11   * </p>
12   * @author <a href="https://www.linkedin.com/in/peterhmjacobs">Peter Jacobs </a>
13   */
14  public final class Primitive
15  {
16      /**
17       * Utility class should not be instantiated.
18       */
19      private Primitive()
20      {
21          // Do not instantiate
22      }
23  
24      /**
25       * casts a set of values to classes.
26       * @param classes Class&lt;?&gt;[]; the classes to cast to
27       * @param values Object[]; the values
28       * @return the newly creates values
29       */
30      public static Object[] cast(final Class<?>[] classes, final Object[] values)
31      {
32          for (int i = 0; i < classes.length; i++)
33          {
34              values[i] = Primitive.cast(classes[i], values[i]);
35          }
36          return values;
37      }
38  
39      /**
40       * casts an object to a instance of clazz.
41       * @param clazz Class&lt;?&gt;; the class to cast to
42       * @param object Object; the object to cast
43       * @return Object; the casted object
44       */
45      public static Object cast(final Class<?> clazz, final Object object)
46      {
47          if (clazz.isInstance(object) || !clazz.isPrimitive() || (clazz.equals(Primitive.getPrimitive(object.getClass()))))
48          {
49              return object;
50          }
51  
52          // Boolean
53          if (clazz.equals(boolean.class))
54          {
55              return Primitive.toBoolean(object);
56          }
57  
58          // Character
59          if (clazz.equals(char.class))
60          {
61              return Primitive.toCharacter(object);
62          }
63  
64          // Byte
65          if (clazz.equals(byte.class))
66          {
67              return Primitive.toByte(object);
68          }
69  
70          // Double
71          if (clazz.equals(double.class))
72          {
73              return Primitive.toDouble(object);
74          }
75  
76          // Float
77          if (clazz.equals(float.class))
78          {
79              return Primitive.toFloat(object);
80          }
81  
82          // Long
83          if (clazz.equals(long.class))
84          {
85              return Primitive.toLong(object);
86          }
87  
88          // Integer
89          if (clazz.equals(int.class))
90          {
91              return Primitive.toInteger(object);
92          }
93  
94          // Short
95          if (clazz.equals(short.class))
96          {
97              return Primitive.toShort(object);
98          }
99          return object;
100     }
101 
102     /**
103      * returns the primitiveClass of the name given as defined by the Java VM class constants. (i.e. both "int" and "I" return
104      * int.class). Both void and "V" return void.class. null is returned whenever an unknown className is given.
105      * @param className String; the className
106      * @return Class the primitiveClass
107      */
108     public static Class<?> forName(final String className)
109     {
110         if (className.equals("int") || className.equals("I"))
111         {
112             return int.class;
113         }
114         if (className.equals("double") || className.equals("D"))
115         {
116             return double.class;
117         }
118         if (className.equals("byte") || className.equals("B"))
119         {
120             return byte.class;
121         }
122         if (className.equals("float") || className.equals("F"))
123         {
124             return float.class;
125         }
126         if (className.equals("long") || className.equals("J"))
127         {
128             return long.class;
129         }
130         if (className.equals("boolean") || className.equals("Z"))
131         {
132             return boolean.class;
133         }
134         if (className.equals("char") || className.equals("C"))
135         {
136             return char.class;
137         }
138         if (className.equals("short") || className.equals("S"))
139         {
140             return short.class;
141         }
142         if (className.equals("void") || className.equals("V"))
143         {
144             return void.class;
145         }
146         return null;
147     }
148 
149     /**
150      * gets the primitive of the given wrapperClass.
151      * @param wrapperClass Class&lt;?&gt;; the wrapper class
152      * @return the primitive Class. null is returned whenever wrapperClass is not a wrapperclass.
153      */
154     public static Class<?> getPrimitive(final Class<?> wrapperClass)
155     {
156         if (wrapperClass.equals(Integer.class))
157         {
158             return int.class;
159         }
160         if (wrapperClass.equals(Double.class))
161         {
162             return double.class;
163         }
164         if (wrapperClass.equals(Byte.class))
165         {
166             return byte.class;
167         }
168         if (wrapperClass.equals(Float.class))
169         {
170             return float.class;
171         }
172         if (wrapperClass.equals(Long.class))
173         {
174             return long.class;
175         }
176         if (wrapperClass.equals(Boolean.class))
177         {
178             return boolean.class;
179         }
180         if (wrapperClass.equals(Character.class))
181         {
182             return char.class;
183         }
184         if (wrapperClass.equals(Short.class))
185         {
186             return short.class;
187         }
188         return null;
189     }
190 
191     /**
192      * gets the wrapper of this primitive class.
193      * @param primitiveClass Class&lt;?&gt;; the primitive class
194      * @return the Class. null is returned whenever wrapperClass is not a wrapperclass.
195      */
196     public static Class<?> getWrapper(final Class<?> primitiveClass)
197     {
198         if (primitiveClass.equals(int.class))
199         {
200             return Integer.class;
201         }
202         if (primitiveClass.equals(double.class))
203         {
204             return Double.class;
205         }
206         if (primitiveClass.equals(byte.class))
207         {
208             return Byte.class;
209         }
210         if (primitiveClass.equals(float.class))
211         {
212             return Float.class;
213         }
214         if (primitiveClass.equals(long.class))
215         {
216             return Long.class;
217         }
218         if (primitiveClass.equals(boolean.class))
219         {
220             return Boolean.class;
221         }
222         if (primitiveClass.equals(char.class))
223         {
224             return Character.class;
225         }
226         if (primitiveClass.equals(short.class))
227         {
228             return Short.class;
229         }
230         throw new IllegalArgumentException(primitiveClass + " != primitive");
231     }
232 
233     /**
234      * casts an object to Boolean.
235      * @param object Object; the object
236      * @return Boolean
237      */
238     public static Boolean toBoolean(final Object object)
239     {
240         if (object instanceof Number)
241         {
242             int value = ((Number) object).intValue();
243             if (value == 1)
244             {
245                 return Boolean.TRUE;
246             }
247             if (value == 0)
248             {
249                 return Boolean.FALSE;
250             }
251             throw new IllegalArgumentException("object.intValue !=0 && !=1");
252         }
253         return (Boolean) object;
254     }
255 
256     /**
257      * casts an object to Byte.
258      * @param object Object; the object
259      * @return Byte
260      */
261     public static Byte toByte(final Object object)
262     {
263         if (object instanceof Number)
264         {
265             return Byte.valueOf(((Number) object).byteValue());
266         }
267         return (Byte) object;
268     }
269 
270     /**
271      * casts an object to Character.
272      * @param object Object; the object to parse
273      * @return Integer the result
274      */
275     public static Character toCharacter(final Object object)
276     {
277         if (object instanceof Number)
278         {
279             return Character.valueOf((char) ((Number) object).byteValue());
280         }
281         return (Character) object;
282     }
283 
284     /**
285      * casts an object to Double.
286      * @param object Object; the object to parse
287      * @return Integer the result
288      */
289     public static Double toDouble(final Object object)
290     {
291         return Double.valueOf(((Number) object).doubleValue());
292     }
293 
294     /**
295      * casts an object to Float.
296      * @param object Object; the object to parse
297      * @return Float the result
298      */
299     public static Float toFloat(final Object object)
300     {
301         return Float.valueOf(((Number) object).floatValue());
302     }
303 
304     /**
305      * casts an object to Long.
306      * @param object Object; the object to parse
307      * @return Long the result
308      */
309     public static Long toLong(final Object object)
310     {
311         return Long.valueOf(((Number) object).longValue());
312     }
313 
314     /**
315      * casts an object to Short.
316      * @param object Object; the object to parse
317      * @return Long the result
318      */
319     public static Short toShort(final Object object)
320     {
321         return Short.valueOf(((Number) object).shortValue());
322     }
323 
324     /**
325      * casts an object to Integer.
326      * @param object Object; the object to parse
327      * @return Integer the result
328      */
329     public static Integer toInteger(final Object object)
330     {
331         if (object instanceof Character)
332         {
333             return Integer.valueOf(((Character) object).charValue());
334         }
335         if (object instanceof Boolean)
336         {
337             if (((Boolean) object).booleanValue())
338             {
339                 return Integer.valueOf(1);
340             }
341             return Integer.valueOf(0);
342         }
343         return Integer.valueOf(((Number) object).intValue());
344     }
345 
346     /**
347      * Returns true when the first class is assignable from the second class, e.g. when firstClass is Number and secondClass is
348      * Integer, the result is true (a number is assignable from an integer, i.e. Number n = Integer.valueOf(4) will work, but
349      * Integer i = new Number(4) will not work). This method also takes into account primitive types, so when firstClass is
350      * Number, and secondClass is int, the result is true, or when the firstClass is int, and the second class is Integer /
351      * firstClass is Integer and secondClass is int, the result will also be true.
352      * @param firstClass Class&lt;?&gt;; the class to which secondClass should be assignable
353      * @param secondClass Class&lt;?&gt;; the class from which firstClass should be assignable
354      * @return firstClass.isAssignableFrom(secondClass) taking into acount primitive types
355      */
356     public static boolean isPrimitiveAssignableFrom(final Class<?> firstClass, final Class<?> secondClass)
357     {
358         boolean result = firstClass.isAssignableFrom(secondClass);
359         if (!result)
360         {
361             if (firstClass.isPrimitive())
362             {
363                 result = getWrapper(firstClass).isAssignableFrom(secondClass);
364             }
365             if (!result)
366             {
367                 if (secondClass.isPrimitive())
368                 {
369                     result = firstClass.isAssignableFrom(getWrapper(secondClass));
370                 }
371             }
372         }
373         return result;
374     }
375 }