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