为什么.equals()方法不会覆盖Java中的基元数组?

L.S*_*ner 10 java arrays language-design equals

我目前正在开发一个项目,我希望使用用户名和密码与数据库进行比较来实现登录机制.

我有这样的想法:

public boolean verifyUser( String username, char[] password ) 
{
  List<char[]> dbpass = getPasswords( username );
  if ( dbpass.contains( password ) )
  {
    overwriteWithNonsense( password );
    return true;
  }
  overwriteWithNonsense( password );
  return false;
}
Run Code Online (Sandbox Code Playgroud)

当我注意到我的单元测试失败了.所以我把它一个更深入的了解发现,该Object::equals方法没有覆盖这解释了为什么基本类型数组List::contains始终评估为false.

我知道有一种可能的解决方法:

if ( dbpass.stream().anyMatch( pw -> Arrays.equals( pw, password ) ) )
{
  overwriteWithNonsense( password );
  return true;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么设计师选择保留"默认实现" Object::equals?使用静态实用程序方法实现框架不是更方便Arrays.equals(array1,array2)吗?

Lin*_*ica 6

任何Collections array都是糟糕的设计.它们不应该一起使用.通过引入一个微不足道的东西你可能更好,但需要class:

public class Password{
     private final char[] password;

     public Password(char[] password){
         this.password = password;
     }

     @Override
     public boolean equals(Object obj){
         // equals logic
     }

     @Override
     public int hashCode(){
         // hashCode logic
     }
}
Run Code Online (Sandbox Code Playgroud)

然后有一个List<Password>.(我也缩短了你的verifyUser方法,因为它看起来有点多余):

public boolean verifyUser( String username, char[] password ){
    List<Password> dbpass = getPasswords(username);
    boolean contained = dbpass.contains(new Password(password));
    overwriteWithNonsense(password);
    return contained;
}
Run Code Online (Sandbox Code Playgroud)

(关于它不被覆盖的原因的另一个问题主要是偏离主题,因为只有java-devs才能真正回答这个问题.)