Search code examples
javaspring-securitycastingdowncast

Downcasting Superclass to Subclass passes instanceof but encounters ClassCastException


I have two objects, User and CustomUserDetails which extends User and implements org.springframework.security.core.userdetails.UserDetails;

In my repository layer I make a call to my in-memory database and retrieve a user.

public User findByUsername(String username) {
    CustomUserDetails customUserDetails = new CustomUserDetails();
    User user = em.createQuery("from User where username = :username", User.class)
            .setParameter("username", username).getSingleResult();

    System.out.println(user.toString());

    if(customUserDetails instanceof User) {
        System.out.println("CustomUserDetails instance of User");
        customUserDetails = (CustomUserDetails) user;
        return customUserDetails;
    } else {
        System.out.println("CustomUserDetails is not instance of User");
        throw new ClassCastException();
    }
}

Here is my console output

ID: 1, USERNAME : joe.bloggs@example.com, PASSWORD: gojoe, LIST<ROLE>: ROLE_ADMIN
CustomUserDetails instance of User
java.lang.ClassCastException: model.User cannot be cast to model.CustomUserDetails

Why I am unable to downcast from User to CustomUserDetails even though I have passed the instanceof check? Is UserDetails interface class getting in my way to successfully cast?


Solution

  • You are trying to cast

    customUserDetails = (CustomUserDetails) user;

    but the user is not an instance of that, the user is an instance of User. Try adding a getter to the User class to get the CustomUserDetails or use a if(user instanceof CustomUserDetails){...