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      
056      @Override
057      public final int hashCode() {
058        return typeVariable.hashCode();
059      }
060    
061      
062      @Override
063      public final boolean equals(Object o) {
064        if (o instanceof TypeParameter) {
065          TypeParameter<?> that = (TypeParameter<?>) o;
066          return typeVariable.equals(that.typeVariable);
067        }
068        return false;
069      }
070    
071      
072      @Override
073      public String toString() {
074        return typeVariable.toString();
075      }
076    }