Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forward Reference of Type Parameter in Java Generics

Tags:

java

generics

According to Java Generics FAQ http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ302 a type parameter cannot be forward-referenced in this way

<A extends B, B> // error

but it is ok to have

<A extends List<B>, B> // ok

These two examples are verified with the latest jdk 1.6.0_24.

My question is, where in the language spec this is specified, implied, or deductible(i.e. if it is untrue, other things can blow up). I can't find it anywhere.

Update

In javac7, it is allowed. Intuitively, the order of type parameters doesn't matter; the type system requires that there's no cyclic dependencies among type variables: <A extends B, B extends A>. Previously, this can be guaranteed by forbidding forward reference. Apparently javac 7 is improved to relax the ordering, while detecting cycles regardless of ordering.

like image 439
irreputable Avatar asked Mar 05 '11 04:03

irreputable


People also ask

Can generics take multiple type parameters?

A Generic class can have muliple type parameters.

What is a generic type parameter in Java?

Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.

Do generics prevent type cast errors?

Implementing generics into your code can greatly improve its overall quality by preventing unprecedented runtime errors involving data types and typecasting.


1 Answers

I'm not sure this is true. I looked over the Java Language Specification and in §6.3 there's this discussion of the scopes of type parameters:

The scope of an interface's type parameter is the entire declaration of the interface including the type parameter section itself. Therefore, type parameters can appear as parts of their own bounds, or as bounds of other type parameters declared in the same section.

The scope of a method's type parameter is the entire declaration of the method, including the type parameter section itself. Therefore, type parameters can appear as parts of their own bounds, or as bounds of other type parameters declared in the same section.

The scope of a constructor's type parameter is the entire declaration of the constructor, including the type parameter section itself. Therefore, type parameters can appear as parts of their own bounds, or as bounds of other type parameters declared in the same section.

(My emphasis).

This suggests that in the declaration

that B is indeed in scope when writing A extends B.

Furthermore, §4.4 of the JLS says, when referring to the bound on a type variable, that

The bound consists of either a type variable, or a class or interface type T

Which suggests that not only is B in scope in <A extends B, B>, but that it's a perfectly legal bound on A.

Finally, to top things off, this code compiles in javac:

public class Test {
     public static <A extends B, B> A test(B obj) {
         return null;
     }
}

So I'm pretty sure that this is perfectly legal Java code and that the example you've linked to is either wrong or is referring to something else.

Hope this helps, and let me know if there's a flaw in my reasoning!

like image 97
templatetypedef Avatar answered Oct 02 '22 09:10

templatetypedef