• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.primitives;
18 
19 import static com.google.common.base.Preconditions.checkNotNull;
20 
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.Map;
24 import java.util.Set;
25 
26 /**
27  * Contains static utility methods pertaining to primitive types and their
28  * corresponding wrapper types.
29  *
30  * @author Kevin Bourrillion
31  * @since 1.0
32  */
33 public final class Primitives {
Primitives()34   private Primitives() {}
35 
36   /** A map from primitive types to their corresponding wrapper types. */
37   private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_WRAPPER_TYPE;
38 
39   /** A map from wrapper types to their corresponding primitive types. */
40   private static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE_TYPE;
41 
42   // Sad that we can't use a BiMap. :(
43 
44   static {
45     Map<Class<?>, Class<?>> primToWrap = new HashMap<Class<?>, Class<?>>(16);
46     Map<Class<?>, Class<?>> wrapToPrim = new HashMap<Class<?>, Class<?>>(16);
47 
add(primToWrap, wrapToPrim, boolean.class, Boolean.class)48     add(primToWrap, wrapToPrim, boolean.class, Boolean.class);
add(primToWrap, wrapToPrim, byte.class, Byte.class)49     add(primToWrap, wrapToPrim, byte.class, Byte.class);
add(primToWrap, wrapToPrim, char.class, Character.class)50     add(primToWrap, wrapToPrim, char.class, Character.class);
add(primToWrap, wrapToPrim, double.class, Double.class)51     add(primToWrap, wrapToPrim, double.class, Double.class);
add(primToWrap, wrapToPrim, float.class, Float.class)52     add(primToWrap, wrapToPrim, float.class, Float.class);
add(primToWrap, wrapToPrim, int.class, Integer.class)53     add(primToWrap, wrapToPrim, int.class, Integer.class);
add(primToWrap, wrapToPrim, long.class, Long.class)54     add(primToWrap, wrapToPrim, long.class, Long.class);
add(primToWrap, wrapToPrim, short.class, Short.class)55     add(primToWrap, wrapToPrim, short.class, Short.class);
add(primToWrap, wrapToPrim, void.class, Void.class)56     add(primToWrap, wrapToPrim, void.class, Void.class);
57 
58     PRIMITIVE_TO_WRAPPER_TYPE = Collections.unmodifiableMap(primToWrap);
59     WRAPPER_TO_PRIMITIVE_TYPE = Collections.unmodifiableMap(wrapToPrim);
60   }
61 
add(Map<Class<?>, Class<?>> forward, Map<Class<?>, Class<?>> backward, Class<?> key, Class<?> value)62   private static void add(Map<Class<?>, Class<?>> forward,
63       Map<Class<?>, Class<?>> backward, Class<?> key, Class<?> value) {
64     forward.put(key, value);
65     backward.put(value, key);
66   }
67 
68   /**
69    * Returns an immutable set of all nine primitive types (including {@code
70    * void}). Note that a simpler way to test whether a {@code Class} instance
71    * is a member of this set is to call {@link Class#isPrimitive}.
72    *
73    * @since 3.0
74    */
allPrimitiveTypes()75   public static Set<Class<?>> allPrimitiveTypes() {
76     return PRIMITIVE_TO_WRAPPER_TYPE.keySet();
77   }
78 
79   /**
80    * Returns an immutable set of all nine primitive-wrapper types (including
81    * {@link Void}).
82    *
83    * @since 3.0
84    */
allWrapperTypes()85   public static Set<Class<?>> allWrapperTypes() {
86     return WRAPPER_TO_PRIMITIVE_TYPE.keySet();
87   }
88 
89   /**
90    * Returns {@code true} if {@code type} is one of the nine
91    * primitive-wrapper types, such as {@link Integer}.
92    *
93    * @see Class#isPrimitive
94    */
isWrapperType(Class<?> type)95   public static boolean isWrapperType(Class<?> type) {
96     return WRAPPER_TO_PRIMITIVE_TYPE.containsKey(checkNotNull(type));
97   }
98 
99   /**
100    * Returns the corresponding wrapper type of {@code type} if it is a primitive
101    * type; otherwise returns {@code type} itself. Idempotent.
102    * <pre>
103    *     wrap(int.class) == Integer.class
104    *     wrap(Integer.class) == Integer.class
105    *     wrap(String.class) == String.class
106    * </pre>
107    */
wrap(Class<T> type)108   public static <T> Class<T> wrap(Class<T> type) {
109     checkNotNull(type);
110 
111     // cast is safe: long.class and Long.class are both of type Class<Long>
112     @SuppressWarnings("unchecked")
113     Class<T> wrapped = (Class<T>) PRIMITIVE_TO_WRAPPER_TYPE.get(type);
114     return (wrapped == null) ? type : wrapped;
115   }
116 
117   /**
118    * Returns the corresponding primitive type of {@code type} if it is a
119    * wrapper type; otherwise returns {@code type} itself. Idempotent.
120    * <pre>
121    *     unwrap(Integer.class) == int.class
122    *     unwrap(int.class) == int.class
123    *     unwrap(String.class) == String.class
124    * </pre>
125    */
unwrap(Class<T> type)126   public static <T> Class<T> unwrap(Class<T> type) {
127     checkNotNull(type);
128 
129     // cast is safe: long.class and Long.class are both of type Class<Long>
130     @SuppressWarnings("unchecked")
131     Class<T> unwrapped = (Class<T>) WRAPPER_TO_PRIMITIVE_TYPE.get(type);
132     return (unwrapped == null) ? type : unwrapped;
133   }
134 }
135