7

This code seems to work fine

class Rule<T>
{

    public <T>Rule(T t)
    {

    }
    public <T> void Foo(T t)
    {

    }
 }
  1. Does the method type parameter shadow the class type parameter?
  2. Also when you create an object does it use the type parameter of the class?

example

Rule<String> r = new Rule<String>();

Does this normally apply to the type parameter of the class, in the situation where they do not conflict? I mean when only the class has a type parameter, not the constructor, or does this look for a type parameter in the constructor? If they do conflict how does this change?

SEE DISCUSSION BELOW

if I have a function call

x = <Type Parameter>method(); // this is a syntax error even inside the function or class ; I must place a this before it, why is this, and does everything still hold true. Why don't I need to prefix anything for the constructor call. Shouldn't Oracle fix this.
rubixibuc
  • 7,111
  • 18
  • 59
  • 98

2 Answers2

8

All of your Ts are different, but you can only see it if you call your methods with the complete syntax:

For example, this code is valid:

new <Float>Rule<Integer>().<Character>Foo();

Just to make this easier to explain, let's assume your code is this:

class Rule<A>
{

    public <B>Rule()
    {

    }
    public <C> void Foo()
    {

    }
 }

Then you can explicitly declare generic types like:

new <B>Rule<A>().<C>Foo();

If the types have the same name, the inner-most one will be chosen (the T on the method, not the class):

With this code, taking parameters:

class Rule<T>
{

    public <T>Rule(T t)
    {

    }
    public <T> void Foo(T t)
    {

    }
}

Then this is valid:

new <Float>Rule<Integer>(3.2f); 

Note that T in the constructor is Float, not Integer.

Another example:

class Example<T> {

    public <T> void foo1() {
        // T here is the <T> declared on foo1
    }

    public void foo2() {
        // T here is the <T> declared on the class Example
    }
}

I found another question that deals with calling methods with explicit generic types without something before them. It seems like static imports and same-class method calls are the same. It seems like Java doesn't let you start a line with <Type> for some reason.

Community
  • 1
  • 1
Brendan Long
  • 53,280
  • 21
  • 146
  • 188
  • Very cool :-), so when you say the inner most would be chosen, just to confirm the most rightward one would be chosen? – rubixibuc Apr 14 '12 at 04:58
  • @rubixibuc - No, the one on the method will be chosen. To explicitly declare a generic type on a method, you put it first (`x = callFunction()`). With a class, you put it after the name of the class when you construct it (`new ArrayList()`). If you want to do both, you put the generic type for the constructor first, then the generic type for the class after (`new MyClass()`). – Brendan Long Apr 14 '12 at 05:01
  • Also inside the constructor all T references refer to Flose, and outside they refer to Integer? – rubixibuc Apr 14 '12 at 05:01
  • @rubixibuc - Yes, unless another method overrides `T` (like `Foo` does). – Brendan Long Apr 14 '12 at 05:02
  • It seems that is a syntax error "illegal start of expression" – rubixibuc Apr 14 '12 at 05:03
  • @rubixibuc - In which one? My first example assumes your original code (no parameters). – Brendan Long Apr 14 '12 at 05:04
  • The call to a generic method with a explicit generic parameter type, when I call inside it's own function it still needs an explicit this call. – rubixibuc Apr 14 '12 at 05:08
  • I read somewhere the explicit parameters for methods always need to be prefixed with a class or object even within the function themselves, is this true? – rubixibuc Apr 14 '12 at 05:09
  • The call to the constructor worked as is, I just wanted to make sure I'm making the call right and everything stays the same – rubixibuc Apr 14 '12 at 05:10
  • I'll add it into the question because I'm not sure how to do formatting for code in the comments – rubixibuc Apr 14 '12 at 05:11
  • @rubixibuc - You'd need to post your code for me to understand what's going wrong. Your problem might be that you're trying to use `T` as a variable (it's not -- it actually disappears at compile time). – Brendan Long Apr 14 '12 at 05:11
  • I added the comment to the bottom of the question – rubixibuc Apr 14 '12 at 05:14
  • @rubixibuc - Most likely the parser just can't handle statements that start with `<`. There's [another question on here that deals with this](http://stackoverflow.com/questions/2050317/invoking-statically-imported-method-with-explicit-type-parameters). – Brendan Long Apr 14 '12 at 05:20
1

Does the method type parameter shadow the class type parameter?

The <T> declaration on constructor is not referred to class type. So yes, it shadow the class type parameter.

In this case it is used as a generic type param that you can use with the constructor, for example as argument. Try this constructor:

public <P> Rule(P arg1, P arg2) {    
}

As you can see I define a type <P> and then I use it to be sure that the arguments will be of type P. In your case you are declaring a type that will be valid for the constructor without using it.

Look at this page.

Also when you create an object does it use the type parameter of the class?

Every generic type definition has is scope as a variable. So out of the constructor returns valid the class type.

dash1e
  • 7,677
  • 1
  • 30
  • 35