简体   繁体   中英

unchecked call to … as a member of a raw type

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?

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.

Change your method declaration to

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

And where you have declared DetailToBriefConverter, declare it is as DetailToBriefConverter

public class MainApp {

private Map<String, DetailToBriefConverter<? extends Detail, ? extends Brief>> map = ImmutableMap.<String, DetailToBriefConverter<? extends Detail, ? extends Brief>>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<? extends Detail, ? extends Brief> detailToBriefConverter = mainApp.map.get(type);
    detailToBriefConverter.convert(detail);
    }
}

Basically when you declare the class, you need to specify the types, else you will get the raw types warning

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM