Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why and how are these two conditionals treated differently by the compiler?

The following two code samples represent the same logic. Check to see if a string is null and branch based upon that check. The first sample compiles safely. The second produces a type mismatch error related to 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's going on 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);
}

The compiler error from Eclipse.

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

As requested, here's the relevant portion of the SecurityService interface.

public interface SecurityService {
    public Set<String> getRolesForUser(String userId);
}
like image 688
Mike Yockey Avatar asked Dec 13 '22 05:12

Mike Yockey


2 Answers

The problem should reside in how the compiler interprets the return value of the ternary operator. You might want to take a look at part 15.25 of the JLS or at this question (kinda related because it's even further complicated by autoboxing and it throws an error at runtime instead of at compile time).

Hope this puts you on the right direction.

like image 51
Marsellus Wallace Avatar answered Jan 21 '23 04:01

Marsellus Wallace


It's because Collections.emptySet() returns an untyped Set. Instead, try this:

Collections.<String>emptySet()
like image 24
mike9322 Avatar answered Jan 21 '23 02:01

mike9322