Why and how are these two conditions handled by the compiler differently?

The following two code examples represent the same logic. Check if the row is null and the branch is based on this check. The first sample compiles safely. The second creates a type mismatch error associated with Java generics. My question seems simple enough, but it eludes me. Why does the compiler treat these two statements differently? How can I better understand what is happening here?

/* compiles cleanly */ protected Collection<String> getUserRoles(Object context, Set<String> mappableRoles) { String cookieValue = extractCookieValue(context); if (cookieValue != null) { return securityService.getRolesForUser(cookieValue); } else { return Collections.emptySet(); } } /* produces a compiler error */ protected Collection<String> getUserRoles(Object context, Set<String> mappableRoles) { String cookieValue = extractCookieValue(context); return cookieValue == null ? Collections.emptySet() : securityService.getRolesForUser(cookieValue); } 

Compiler error from Eclipse.

Type mismatch: cannot convert from Set<capture#1-of ? extends Object> to Collection<String>

According to the request, the corresponding part of the SecurityService interface is located here.

 public interface SecurityService { public Set<String> getRolesForUser(String userId); } 
+4
source share
3 answers

The problem should be how the compiler interprets the return value of the ternary operator. You can take a look at part 15.25 of JLS or question (related because it is even more complicated by auto-boxing and it throws an error at runtime, not at compile time).

Hope this puts you in the right direction.

+7
source

This is because Collections.emptySet() returns an untyped Set . Instead, try the following:

 Collections.<String>emptySet() 
+5
source

Collections.emptySet () is declared as

 public static final <T> Set<T> emptySet() 

The first T is used for Type Inference . The second implementation of getUserRoles is too complicated for the java compiler to determine the correct type. Exactly because of this reason. Work:

 protected Collection<String> getUserRoles(Object context, Set<String> mappableRoles) { String cookieValue = extractCookieValue(context); Collection<String> a = null; return cookieValue == null ? a = Collections.emptySet() : securityService.getRolesForUser(cookieValue); } 
+1
source

Source: https://habr.com/ru/post/1392712/


All Articles