The type parameter G is hiding the type G
NickName:Jinnah Ask DateTime:2015-09-28T17:53:25

The type parameter G is hiding the type G

public class MyGenericClass< G> {


    public <G> G genericMethod1(G g){
        System.out.println(g.toString());
        return g;

    }

    public <X> G genericMethod2(G g) {
        System.out.println(g.toString());
        return g;
    }

    public <X> X genericMethod3(G g) {
        System.out.println(g.toString());
        Integer i = new Integer(100);
        return (X) i;       
    }


    public static void main(String... cmdarg) {

        MyGenericClass<Employee> gemp = new MyGenericClass<Employee>();
        Employee e1 = new Employee();
        e1.setName("My Name");


        String resultOfMethod3 = gemp.genericMethod3(e1);
        System.out.println(resultOfMethod3);                            

    }


}

in genericMethod1: I get the compiler warning as "The type parameter G is hiding the type G".

Question: Which G is hidden by this G? What's the actual meaning of this?

genericMethod2 doesn't show any errors/warnings.

Question: I thought it should not compile. why is two different types allowed in same method signature? What can be typical real time example to compare with G and X?

In genericMethod3: I'm intentionally returning an Integer object and in the main method i'm trying to assign the result to a String. As expected: I got the ClassCastException.

Question: Isn't the original purpose of having generics to avoid ClassCastExceptions? Why did the compiler allow it? Is this a bug in the design of Generics?

Copyright Notice:Content Author:「Jinnah」,Reproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/32820133/the-type-parameter-g-is-hiding-the-type-g

Answers
sp00m 2015-09-28T10:04:27

Generics can be used at class level and at method level:\n\n\npublic class MyClass<T>: T is available for all instance members (i.e. non-static) of the class (fields, methods, inner classes...)\npublic (static) <U> ReturnType myMethod(..) {...}: U is available for the method only\n\n\nYou're mixing them.\n\nWith public <G> G genericMethod1(G g), this <G> generic is hiding the class' one since they have the same name, so the latter isn't available in the method anymore. If you want to use the class' generic, don't specify it at the method level: public G genericMethod1(G g).\n\nWith public <X> G genericMethod2(G g), you're defining a generic <X> that isn't used: only the class' generic G is used.\n\nWith public <X> X genericMethod3(G g), you're defining a generic <X> that is used for the return value of the method. In the method body, you're casting an int to X but you can't be sure that X is a super type of int. Technically, this can be done with <X super Integer>, but I'm not sure this is actually what you're looking for.",


Sean Patrick Floyd 2015-09-28T09:58:00

public class MyGenericClass< G> {\n\n\n public <G> G genericMethod1(G g){\n System.out.println(g.toString());\n return g;\n\n }\n\n\nYou have two different <G> variables here, one on class level and one on method level. This is roughly equivalent to having a field and a local variable of the same name. The local variable would \"win\" in that case, just as the method level <G> would override the class-level one. Since this is a common cause of errors, IDEs warn you of this.\n\nMethod 2 doesn't redefine <G>, so it generates no warning.",


More about “The type parameter G is hiding the type G” related questions

The type parameter G is hiding the type G

public class MyGenericClass&lt; G&gt; { public &lt;G&gt; G genericMethod1(G g){ System.out.println(g.toString()); return g; } public &lt;X&gt; G genericMethod2(G g) {..

Show Detail

generics type parameter hiding the type

I created the interface Card as follows public interface Card extends Comparable&lt;Card&gt; { ..... } then public interface Deck&lt;Card&gt; { public void add(Card card...

Show Detail

Type of f g x = g . g x

It is not clear to me why the function defined as f g x = g . g x has the type f :: (b -&gt; a -&gt; b) -&gt; b -&gt; a -&gt; a -&gt; b I would have thought it would be of type f :: (t -

Show Detail

The type parameter FooEntity is hiding the type FooEntity

public interface IFoo&lt;TKey, FooEntity&lt;TValue&gt;&gt; { // stuff } I get this error: The type parameter FooEntity is hiding the type FooEntity public class FooEntity&lt;T&gt; { priv

Show Detail

Java generics - The type parameter String is hiding the type String

In my interface: public &lt;T&gt; Result query(T query) In my 1st subclass: public &lt;HashMap&gt; Result query(HashMap queryMap) In my 2nd subclass: public &lt;String&gt; Result query(S

Show Detail

The type parameter is X hiding the type X

I'm trying to implement this code. Rent is a subclass of Transaction. import java.util.LinkedList; public class TransactionList&lt;Transaction&gt; extends LinkedList { //TransactionList: warning: ...

Show Detail

How to type `let rec f g = g f` in OCaml?

Here’s what the interpreter gives me: # let rec f g = g f ;; Error: This expression has type ('a -&gt; 'b) -&gt; 'c but an expression was expected of type 'a The type variable 'a o

Show Detail

Why the type parameter Entry is hiding the type Map.Entry?

Eclipse complains about this code with "The type parameter Entry is hiding the type Map.Entry": import java.util.Map.Entry; public class Test { static abstract class EntryIterator&lt;Entry&l...

Show Detail

Java type parameter is hiding a generic type?

I have a generic class: public class Widget&lt;COMMAND&gt; { // ... } So I can create instances of it like: Widget&lt;Fizz&gt; fizzWidget = new Widget&lt;Fizz&gt;(); Then I have an AB

Show Detail

Java generics: the type parameter T is hiding the type T

Why java compiler is giving me "the type parameter T is hiding the type T" in the "translate" method ? public static interface Translator&lt;T, E&gt; { E call(T t); } public static &lt;T, E&g

Show Detail