Saturday 23 November 2019

java - Collections.emptyList() returns a List?




I'm having some trouble navigating Java's rule for inferring generic type parameters. Consider the following class, which has an optional list parameter:



import java.util.Collections;
import java.util.List;

public class Person {
private String name;
private List nicknames;


public Person(String name) {
this(name,Collections.emptyList());
}

public Person(String name,List nicknames) {
this.name = name;
this.nicknames = nicknames;
}
}



My Java compiler gives the following error:



Person.java:9: The constructor Person(String, List) is undefined


But Collections.emptyList() returns type List, not List. Adding a cast doesn't help



public Person(String name) {
this(name,(List)Collections.emptyList());

}


yields



Person.java:9: inconvertible types


Using EMPTY_LIST instead of emptyList()




public Person(String name) {
this(name,Collections.EMPTY_LIST);
}


yields



Person.java:9: warning: [unchecked] unchecked conversion



Whereas the following change makes the error go away:



public Person(String name) {
this.name = name;
this.nicknames = Collections.emptyList();
}


Can anyone explain what type-checking rule I'm running up against here, and the best way to work around it? In this example, the final code example is satisfactory, but with larger classes, I'd like to be able to write methods following this "optional parameter" pattern without duplicating code.




For extra credit: when is it appropriate to use EMPTY_LIST as opposed to emptyList()?


Answer



The issue you're encountering is that even though the method emptyList() returns List, you haven't provided it with the type, so it defaults to returning List. You can supply the type parameter, and have your code behave as expected, like this:



public Person(String name) {
this(name,Collections.emptyList());
}


Now when you're doing straight assignment, the compiler can figure out the generic type parameters for you. It's called type inference. For example, if you did this:




public Person(String name) {
List emptyList = Collections.emptyList();
this(name, emptyList);
}


then the emptyList() call would correctly return a List.


No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...