    001    /*
    002     * Copyright (C) 2011 The Guava Authors
    003     *
    004     * Licensed under the Apache License, Version 2.0 (the "License");
    005     * you may not use this file except in compliance with the License.
    006     * You may obtain a copy of the License at
    007     *
    008     * http://www.apache.org/licenses/LICENSE-2.0
    009     *
    010     * Unless required by applicable law or agreed to in writing, software
    011     * distributed under the License is distributed on an "AS IS" BASIS,
    012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    013     * See the License for the specific language governing permissions and
    014     * limitations under the License.
    015     */
    016
    017    package com.google.common.reflect;
    018
    019    import static com.google.common.base.Preconditions.checkArgument;
    020    import static com.google.common.base.Preconditions.checkNotNull;
    021
    022    import com.google.common.annotations.Beta;
    023
    024    import java.lang.reflect.Type;
    025    import java.lang.reflect.TypeVariable;
    026
    027    /**
    028     * Captures a free type variable that can be used in {@link TypeToken#where}.
    029     * For example: <pre>   {@code
    030     *
    031     *   static <T> TypeToken<List<T>> listOf(Class<T> elementType) {
    032     *     return new TypeToken<List<T>>() {}
    033     *         .where(new TypeParameter<T>() {}, elementType);
    034     *   }
    035     * }</pre>
    036     *
    037     * @author Ben Yu
    038     * @since 12.0
    039     */
    040    @Beta
    041    public abstract class TypeParameter<T> extends TypeCapture<T> {
    042
    043      final TypeVariable<?> typeVariable;
    044
    045      private TypeParameter(TypeVariable<?> typeVariable) {
    046        this.typeVariable = checkNotNull(typeVariable);
    047      }
    048
    049      protected TypeParameter() {
    050        Type type = capture();
    051        checkArgument(type instanceof TypeVariable, "%s should be a type variable.", type);
    052        this.typeVariable = (TypeVariable<?>) type;
    053      }
    054
    055      @Override public final int hashCode() {
    056        return typeVariable.hashCode();
    057      }
    058
    059      @Override public final boolean equals(Object o) {
    060        if (o instanceof TypeParameter) {
    061          TypeParameter<?> that = (TypeParameter<?>) o;
    062          return typeVariable.equals(that.typeVariable);
    063        }
    064        return false;
    065      }
    066
    067      @Override public String toString() {
    068        return typeVariable.toString();
    069      }
    070    }