classpath
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]