steady rain
steady rain

Reputation: 2336

Enforce generic types in java property declaration

Java code:

class First {}
class Second extends First {}
class Jinkies<T> {}
interface Greeting<T> {}
class Hello<U extends T, T> implements Greeting<T> {
  private Map<Jinkies<U>, List<U>> scooby;
}

In the declaration of scooby, both Jinkies and List have the same type parameter - that's what I want to enforce. Is there a way to achieve this in Java without having to resort to listing two parameters (U and T) in the declaration of Hello class?

I'd like to have only one - e.g. something like:

class Hello<U extends T> implements Greeting<T> 

however, that doesn't compile. I have to write:

new Hello<Second, First>()

instead of:

new Hello<Second>()

even though I don't care about First anywhere in the body of Hello (nor do the users of Hello).

Edit - as @LouisWasserman explains in the comment, bad example on my part above. Maybe to clarify - let's say I always want to do:

new Hello<First>()

but then be able to use any U where U extends First (i.e. First or Second in the above example) throughout the body of Hello without caring for First and with making sure that U is always the same. That is, if I had two methods:

void method1(U a) {}
void method2(U b) {}

I'd like to be able to enforce that U of the first method is the same as the U of the second method - but not care about what it is (i.e. First or Second), as long as it is the same.

<U extends T> void method1(U a) {}
<U extends T> void method2(U b) {}

would not work, as I could call method1(first) and method2(second).

Edit - thinking this through, this probably would not work the other way. I.e. if only specifying one bound, it would be possible to go the other way. So if specifying First only, I could "downcast" to a Third. If specifying Second only, I could "upcast" to a Zero. Back to the laboratory...

Upvotes: 4

Views: 1341

Answers (1)

libik
libik

Reputation: 23049

This is the same class definition, but maybe it is more visible now with different generic names :

class Jinkies<X> {}
interface Greeting<Y> {}
class Hello<T,U extends T> implements Greeting<T> {
  private Map<Jinkies<U>, List<U>> scooby;
}

As you can see, without specifing T in declaration like new Hello<Second, First>(), you cannot say what T is.

Upvotes: 2

Related Questions