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    }