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-2020 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<?>[]; 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<?>; 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<?>; 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<?>; 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 the class to which secondClass should be assignable
353 * @param secondClass 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 }