Что будет в результате компиляции и исполнения следующего кода:

class User {
    private int id = 0;
    private String name;
    private String surname;
    
    public User() {}
    
    public User(int id, String name, String surname) {
        this.id = id;
        this.name = name;
        this.surname = surname;
    }

    @Override
    public boolean equals(Object obj) {
        
        if (this == obj)
            return true;
        
        if (obj == null || !getClass().equals(obj.getClass()))
            return false;
        
        User u = (User) obj;
        
        return id == u.id
            && name == u.name || (name != null && name.equals(u.name))
            && surname == u.surname || (surname != null && surname.equals(u.surname));
        
    }
    
    @Override
    public int hashCode() {
        
        return id +
            name == null ? 0 : name.hashCode() +
            surname == null ? 0 : surname.hashCode();
    }
    
    public static void main(String args[]) {

        User u1 = new User(12, "name", null);
        User u2 = new User(12, null, "name");
        
        System.out.println(u1.hashCode() == u2.hashCode());
        System.out.println(u1.equals(u2));
    }
}
Explanation
Фактический ход выполнения метода hashCode:

return ((id + name) == null ? 0 : name.hashCode() + surname) == null ? 0 : surname.hashCode();
Из-за этого null-поля типа String конкатенируются с цифрами и проходят проверку на null. Если написать:

return id +
    (name == null ? 0 : name.hashCode()) +
    (surname == null ? 0 : surname.hashCode());
то выполнение пройдёт нормально и результат будет:
true
false

Следи за CodeGalaxy

Мобильное приложение Beta

Get it on Google Play
Обратная Связь
Продолжайте изучать
тесты по Java
Cosmo
Зарегистрируйся сейчас
или Подпишись на будущие тесты