[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [japitools] more generic evilness - is this legal?
From: |
David Holmes |
Subject: |
RE: [japitools] more generic evilness - is this legal? |
Date: |
Tue, 13 Sep 2005 10:09:58 +1000 |
Stuart,
> class Outer<T> {
> class Inner<U> {
> }
> class InnerTester extends Inner {
> }
> public InnerTester getIt() { return new InnerTester(); }
> }
Okay. InnerTester is a non-generic class that extends the raw type Inner.
> public class Tester2 {
> public static Outer<String>.InnerTester getIt() {
> return new Outer<String>().getIt();
> }
This is okay. Outer is correctly parameterized and InnerTester takes no
parameter so Outer<String>.InnerTester is a correctly formed type.
> // Fails to compile because Inner is "half-bound"
> // But for some reason InnerTester is okay even though it results in
> // Inner being equally half-bound.
> //public static Outer<String>.Inner getIt2() {
> // return new Outer<String>().getIt();
> //}
You cannot have mixed-rawness, it is all or nothing. So either supply a type
parameter for Inner or use the fully raw type Outer.Inner. In the former
case you'll then get an unchecked warning because although an InnerTester
is-a Inner, it may not be an Inner<String> for example.
The distinction between the two cases is that InnerTester is NOT a generic
type.
> The bit that fails to compile is obvious - you can't have
> Outer<String>.Inner because T is bound but U is not. However, I can't
> understand why InnerTester is legal, because it's in exactly the same
> boat - in fact, it's superclass *is* Outer<String>.Inner.
It's immediate superclass is the raw type Inner. It's super-superclass is
the generic type Outer<T>. Because it is a non-static nested class it will
have an enclosing instance that is some parameterized form of Outer.
> The rules as I understood them were that you could have a raw type,
> with all generic parameters omitted, or a fully-qualified type with
> all the parameters specified, but specifying some but not all was
> illegal. This appears to be an exception to that rule?
The rule applies to generic types. InnerTester is NOT a generic type.
> It gets worse...
> class Inner<U> {
> class InnerInner<V> {}
> }
> class InnerTester extends Inner {
> InnerInner<String> foo;
> }
>
> Now InnerInner has T bound, U unbound and V bound - there's a hole in
> the *middle* of the list of parameters. Is this *really* supposed to
> be legal?
You description isn't appropriate. InnerInner is a generic type that happens
to be nested in another generic type. So you can declare a field of type
InnerInner<X> for any X. Trying to actually create an instance to store in
that field will require binding the enclosing type suitably.
Raw types make things very messy. I think your are confusing the nesting
aspects and the inheriting aspects of types.
Hope this helps.
David Holmes