简体   繁体   中英

Type safety: Unchecked cast when extending generics

I have the following method

private ResponseEntity<? extends ResourceSupport> createResponse(boolean isError) {
    if(isError){
        return new ResponseEntity<ErrorResource>((ErrorResource) new ErrorResource());
    }
    return new ResponseEntity<ResourceSupport>(new ResourceSupport());
}

I call this method to get the error resource

ResponseEntity<ErrorResource> e = (ResponseEntity<ErrorResource>) createResponse(logoutResult, userId);
System.out.println(e.getError());

When I do this I get this error:

"Type safety: Unchecked cast from ResponseEntity<capture#1-of ? extends ResourceSupport> to ResponseEntity<ErrorResource>"

Is there a way to cast the object without suppressing the error message?

You use the same method to return apples and oranges instances. At runtime, because of java's type erasure, the system has no way of knowing if that cast is allowed or not, hence the warning. You have 2 ways to avoid it:

a) Create 2 different methods:

private ResponseEntity<ResourceSupport> createResponse() {
    return new ResponseEntity<ResourceSupport>(new ResourceSupport());
}

private ResponseEntity<ErrorResource> createErrorResponse() {
    return new ResponseEntity<ErrorResource>(new ErrorResource());
}

b) Make the method fully generic by passing the actual ResourceSupport instance as parameter:

private <T extends ResourceSupport> ResponseEntity<T> createResponse(T resource) {
    return new ResponseEntity<T>(resource);
}

The solution is: don't try to cast to ResponseEntity<ResourceSupport> , but leave the type as is like ResponseEntity<? extends ResourceSupport> ResponseEntity<? extends ResourceSupport> :

ResponseEntity<? extends ResourceSupport> e = createResponse(logoutResult, userId);
System.out.println(e.getError());

The types are ResponseEntity<ErrorResource> and ResponseEntity<ResourceSupport> cannot be assigned to eachother (try it).

But your original code tried to do just that - in the case that there is no error, your createResponse method returns a new ResponseEntity<ResourceSupport>(new ResourceSupport()) but you try to cast that to a ResponseEntity<ErrorResource> , which is not allowed.

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