Home | History | Annotate | Download | only in primitives
      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 {
     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 
     48     add(primToWrap, wrapToPrim, boolean.class, Boolean.class);
     49     add(primToWrap, wrapToPrim, byte.class, Byte.class);
     50     add(primToWrap, wrapToPrim, char.class, Character.class);
     51     add(primToWrap, wrapToPrim, double.class, Double.class);
     52     add(primToWrap, wrapToPrim, float.class, Float.class);
     53     add(primToWrap, wrapToPrim, int.class, Integer.class);
     54     add(primToWrap, wrapToPrim, long.class, Long.class);
     55     add(primToWrap, wrapToPrim, short.class, Short.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 
     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    */
     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    */
     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    */
     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    */
    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    */
    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