Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unchecked call to ... as a member of a raw type

Tags:

java

generics

I'm converting people's data into condensed form. So I have a bunch of interfaces:

public interface Brief {}
public interface Detail {}

public interface DetailToBriefConverter<T extends Detail, R extends Brief>  {
    R convert(T detail);
}

, a bunch of pojos:

public class StudentBrief implements Brief {...}
public class StudentDetail implements Detail {...}
public class EmployeeBrief implements Brief {...}
public class EmployeeDetail implements Detail {...}

and converters:

public class StudentDetailToBriefConverter implements DetailToBriefConverter<StudentDetail, StudentBrief> {
@Override
public StudentBrief convert(StudentDetail detail) {
    // logic here
    }
}

etc.

My main class looks roughly like this:

public class MainApp {

private Map<String, DetailToBriefConverter> map = ImmutableMap.<String, DetailToBriefConverter>builder()
        .put("employee", new EmployeeDetailToBriefConverter())
        .put("student", new StudentDetailToBriefConverter())
        .build();

public static void main(String[] args) {
    MainApp mainApp = new MainApp();
    String type = "employee"; // comes from the request actually
    Detail detail = new EmployeeDetail(); // comes from the request
    DetailToBriefConverter detailToBriefConverter = mainApp.map.get(type);
    detailToBriefConverter.convert(detail);
    }
}

And this works, but I get a warning unchecked call to convert(T) as a member of a raw type DetailToBriefConverter.

How can I get rid of this warning or do I have to live with it?

like image 549
J.Doe Avatar asked Aug 07 '18 21:08

J.Doe


1 Answers

DetailToBriefConverter detailToBriefConverter = mainApp.map.get(type);

detailToBriefConverter is a raw type: you aren't giving it a type parameter. Nor are you giving it one in the map.

Given that you are putting heterogeneous types into the map, the only type parameter you can use is <?, ?>:

DetailToBriefConverter<?, ?> detailToBriefConverter = mainApp.map.get(type);

(add it to the map declaration too)

But then you've got the problem that you can't invoke detail like this:

detailToBriefConverter.convert(detail);

because the type of the parameter is ?, and you've got an EmployeeDetail, or whatever it is called.

Basically, what you are trying to do isn't type safe. It is possible that you can write the code in such a way that you don't actually get any runtime exceptions; but it's rather brittle.


What you really need is a type-safe heterogeneous container. Look it up in Effective Java or elsewhere.

like image 73
Andy Turner Avatar answered Sep 21 '22 11:09

Andy Turner