14

I want to provide something like this in my api:

class Foobar extends AbstractThing<Double>

class EventThing<Foobar> {    
            public Foobar getSource();
            public Double getValue();
}

So I write this:

class EventThing<T extends AbstractThing<U>> {    
        public T getSource();
        public U getValue();
}

But java can not resolve the U.

With EventThing<T extends AbstractThing<U>,U> instead it works, but the second U is actually redundant 'cause the AbtractThing define the Type already. So I love to get rid of it.

Marcel Jaeschke
  • 707
  • 7
  • 24

1 Answers1

33

You can't get rid of it. The second U is not redundant. You want the compiler to interpret the first U as a type parameter, but it doesn't. You could also have written this:

class EventThing<T extends AbstractThing<Double>>

Note that Double in this case is a concrete class, and not a type parameter. Compare this to the following:

class EventThing<T extends AbstractThing<U>>

Note that this has the exact same form as the first line of code above. How is the compiler supposed to know that in the first case, Double is meant as a concrete class, while in the second case, U is meant as a type parameter?

The compiler can't know that, and treats the U as a concrete class, just like the Double in the first line. The only way to let the compiler know that U is a type parameter is to specify it as such:

class EventThing<T extends AbstractThing<U>, U>
Jesper
  • 202,709
  • 46
  • 318
  • 350
  • 1
    It seems to me more like an missing feature of the compiler. EDIT: But I get your point, thanks for you answer. To bad. I think I will left the hole feature out. – Marcel Jaeschke Dec 15 '10 at 16:31
  • 4
    @Marcel: I think this answer explains quite clearly why the compiler cannot (and should not) attempt to guess at whether `U` is an actual type or a generic type parameter. Java requires that each generic type parameter be declared explicitly for good reason. Regardless of what it seems like to you, this is not a "missing feature of the compiler." – ColinD Dec 15 '10 at 17:10
  • 1
    @ColinD: I agree with Marcel that it does seem like a missing feature and U in his example does seem redundant. While, obviously, the compiler must be informed that U is a type argument we could have something like: class EventThing>, essentially saying: U is a variable type parameter, now go and infer it yourself (character % used for discussion purpose only, I agree it's ugly). This way there would be no repetition in the calling code. – Gilead Nov 28 '12 at 11:48
  • @Gilead: I really don't see any value in the idea of introducing a special character for marking something like that. It'd be ugly regardless of what you choose, and it would complicate the language syntax and the compilation process. And it saves what, all of 2 characters? You're not even considering the case where the type U might be bounded ("U extends Foo") and might be used in the bounds of two or more other type parameters. What you and Marcel suggest would not only be strange and inconsistent with itself, it just wouldn't work. – ColinD Nov 29 '12 at 03:47
  • 2
    @ColinD Just to be clear: I never suggest a special character. This was Gilead idea not mine! Beside of that I still think that my origin idea is a kind of missing feature. The only problem is, that the compiler can not handle it, because it do not expect a new type parameter at this position. I don't think it will break something or would be inconsistent. It's like the diamond think in jre7. The feature was not necessary needed but at least for some people it seems to be useful. BTW: I still prefer Lists.newXyzList() over new XyzList<>(). – Marcel Jaeschke Jul 29 '13 at 12:26