• 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"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 
15 package com.google.common.primitives;
16 
17 import static com.google.common.base.Preconditions.checkNotNull;
18 
19 import com.google.common.annotations.GwtIncompatible;
20 import java.util.Collections;
21 import java.util.LinkedHashMap;
22 import java.util.Map;
23 import java.util.Set;
24 
25 /**
26  * Contains static utility methods pertaining to primitive types and their corresponding wrapper
27  * types.
28  *
29  * @author Kevin Bourrillion
30  * @since 1.0
31  */
32 @GwtIncompatible
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 LinkedHashMap<>(16);
46     Map<Class<?>, Class<?>> wrapToPrim = new LinkedHashMap<>(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(
63       Map<Class<?>, Class<?>> forward,
64       Map<Class<?>, Class<?>> backward,
65       Class<?> key,
66       Class<?> value) {
67     forward.put(key, value);
68     backward.put(value, key);
69   }
70 
71   /**
72    * Returns an immutable set of all nine primitive types (including {@code void}). Note that a
73    * simpler way to test whether a {@code Class} instance is a member of this set is to call {@link
74    * Class#isPrimitive}.
75    *
76    * @since 3.0
77    */
allPrimitiveTypes()78   public static Set<Class<?>> allPrimitiveTypes() {
79     return PRIMITIVE_TO_WRAPPER_TYPE.keySet();
80   }
81 
82   /**
83    * Returns an immutable set of all nine primitive-wrapper types (including {@link Void}).
84    *
85    * @since 3.0
86    */
allWrapperTypes()87   public static Set<Class<?>> allWrapperTypes() {
88     return WRAPPER_TO_PRIMITIVE_TYPE.keySet();
89   }
90 
91   /**
92    * Returns {@code true} if {@code type} is one of the nine primitive-wrapper types, such as {@link
93    * Integer}.
94    *
95    * @see Class#isPrimitive
96    */
isWrapperType(Class<?> type)97   public static boolean isWrapperType(Class<?> type) {
98     return WRAPPER_TO_PRIMITIVE_TYPE.containsKey(checkNotNull(type));
99   }
100 
101   /**
102    * Returns the corresponding wrapper type of {@code type} if it is a primitive type; otherwise
103    * returns {@code type} itself. Idempotent.
104    *
105    * <pre>
106    *     wrap(int.class) == Integer.class
107    *     wrap(Integer.class) == Integer.class
108    *     wrap(String.class) == String.class
109    * </pre>
110    */
wrap(Class<T> type)111   public static <T> Class<T> wrap(Class<T> type) {
112     checkNotNull(type);
113 
114     // cast is safe: long.class and Long.class are both of type Class<Long>
115     @SuppressWarnings("unchecked")
116     Class<T> wrapped = (Class<T>) PRIMITIVE_TO_WRAPPER_TYPE.get(type);
117     return (wrapped == null) ? type : wrapped;
118   }
119 
120   /**
121    * Returns the corresponding primitive type of {@code type} if it is a wrapper type; otherwise
122    * returns {@code type} itself. Idempotent.
123    *
124    * <pre>
125    *     unwrap(Integer.class) == int.class
126    *     unwrap(int.class) == int.class
127    *     unwrap(String.class) == String.class
128    * </pre>
129    */
unwrap(Class<T> type)130   public static <T> Class<T> unwrap(Class<T> type) {
131     checkNotNull(type);
132 
133     // cast is safe: long.class and Long.class are both of type Class<Long>
134     @SuppressWarnings("unchecked")
135     Class<T> unwrapped = (Class<T>) WRAPPER_TO_PRIMITIVE_TYPE.get(type);
136     return (unwrapped == null) ? type : unwrapped;
137   }
138 }
139