Search code examples
javaspringgenericstype-safety

Does a method's return value guarantee type safety?


I'm using Spring's ResponseEntity as an example but I'm not sure why specifying a generic's type in a method signature works generally. If I have a controller method that returns a ResponseEntity then it seems I don't need to specify String again when I create the ResponseEntity in the method.

Is this the equivalent of "ArrayList list = new ArrayList<>()" or have I misunderstood?

Here's an example from the Spring docs:

@RequestMapping("/handle")
public ResponseEntity<String> handle() {
   HttpHeaders responseHeaders = new HttpHeaders();
   responseHeaders.set("MyResponseHeader", "MyValue");
   return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED);
}

IntelliJ code analysis will point out that explicit typing in the return is redundant so I could do this instead:

return new ResponseEntity<>("Hello World", responseHeaders, HttpStatus.CREATED);

Is this due to the compiler checking the method signature or is there something less obvious happening? If I change the code to:

return new ResponseEntity<>(123, responseHeaders, HttpStatus.CREATED);

then I'll (correctly) get a compiler warning.


Solution

  • Correct, starting with Java 7, the compiler can infer the type without it being explicitly defined. See: https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html

    From the Spring JavaDocs you can see ResponseEntity declared as public class ResponseEntity<T> extends HttpEntity<T> so when you specify ResponseEntity<String> as the return type, the Java compiler can infer this in the return statement return new ResponseEntity<>(...)