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