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
017package com.google.common.reflect;
018
019import static com.google.common.base.Preconditions.checkArgument;
020
021import com.google.common.annotations.Beta;
022
023import java.lang.reflect.Type;
024import java.lang.reflect.TypeVariable;
025
026import javax.annotation.Nullable;
027
028/**
029 * Captures a free type variable that can be used in {@link TypeToken#where}.
030 * For example:
031 *
032 * <pre>   {@code
033 *   static <T> TypeToken<List<T>> listOf(Class<T> elementType) {
034 *     return new TypeToken<List<T>>() {}
035 *         .where(new TypeParameter<T>() {}, elementType);
036 *   }}</pre>
037 *
038 * @author Ben Yu
039 * @since 12.0
040 */
041@Beta
042public abstract class TypeParameter<T> extends TypeCapture<T> {
043
044  final TypeVariable<?> typeVariable;
045
046  protected TypeParameter() {
047    Type type = capture();
048    checkArgument(type instanceof TypeVariable, "%s should be a type variable.", type);
049    this.typeVariable = (TypeVariable<?>) type;
050  }
051
052  @Override public final int hashCode() {
053    return typeVariable.hashCode();
054  }
055
056  @Override public final boolean equals(@Nullable Object o) {
057    if (o instanceof TypeParameter) {
058      TypeParameter<?> that = (TypeParameter<?>) o;
059      return typeVariable.equals(that.typeVariable);
060    }
061    return false;
062  }
063
064  @Override public String toString() {
065    return typeVariable.toString();
066  }
067}