开发者

Why does this generic code compile?

开发者 https://www.devze.com 2023-02-11 12:09 出处:网络
Javac infers that T is String in method f(). Which rules in language spec lead to that c开发者_如何学JAVAonclusion?

Javac infers that T is String in method f(). Which rules in language spec lead to that c开发者_如何学JAVAonclusion?

<T> T g(){ return null; }

String f()
{
    return g();
}


I suspect the compiler is effectively using section 15.12.2.8:

If the method result occurs in a context where it will be subject to assignment conversion (§5.2) to a type S, then let R be the declared result type of the method

This is treating the return statement as if it were subject to assignment conversion. For example, imagine we converted f() to:

String f()
{
    String tmp = g();
    return tmp;
}

Now as to whether it is subject to assignment conversion, section 14.17 (the return statement) contains this:

A return statement with an Expression must be contained in a method declaration that is declared to return a value (§8.4) or a compile-time error occurs. The Expression must denote a variable or value of some type T, or a compile-time error occurs. The type T must be assignable (§5.2) to the declared result type of the method, or a compile-time error occurs.

That reference to 5.2 is the "assignment conversion" section, so I guess that means the expression g() is "subject to assignment conversion", leading to that part of section 15.12.2.8 being applicable.


T is inferred to be a String because the generic return type of g() is used as the return type of f(), which is strongly typed to a String. In order for the statement to be valid, T must be a String, so it is.


Because g is a generic method, Java infers the type of g to match the return type of f.

You can see this by trying the following three functions.

class SomeClass{

   <T> T g(){return null;}

   String f() {
      return this.<String>g();
   }

   Integer h() {
      return this.<Integer>g();
   }

   Integer i() {
      return this.<String>g();
   }
}

f and h will compile fine because it infers the type from the return type. i will not compile because the types do not match.

0

精彩评论

暂无评论...
验证码 换一张
取 消