为什么 .equals() 方法没有被 Java 中的原语数组覆盖?



我目前正在做一个项目,我想使用用户名和密码来实现登录机制,并与数据库进行比较。

我有这样的想法:

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

当我注意到我的单元测试失败时。所以我更深入地研究了它,注意到Object::equals方法没有被原语数组覆盖,这解释了为什么List::contains总是计算为false

我知道有一个可能的解决方法,使用:

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

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

array的任何Collection大多是糟糕的设计。它们不应一起使用。引入一个琐碎但需要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
}
}

然后有一个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;
}

(你关于为什么它没有被覆盖的另一个问题大多是题外话,因为只有java开发人员才能真正回答这个问题。

在 Java中array不是一个类,但在 Java Doc 第 4.3.1 节中,它被视为一个对象。现在,由于这不是一个类,因此没有用于equals/hashCode的代码。

现在,对于要比较数组的解决方案,您可以使用Arrays.equals方法来比较两个数组:

public boolean verifyUser( String username, char[] password ) 
{
List<char[]> dbpass = getPasswords( username );
for(char[] arr : dbpass)
{
if ( Arrays.equals(arr,password) )
{
overwriteWithNonsense( password );
return true;
}
}
overwriteWithNonsense( password );
return false;
}

我认为没有充分的理由。通常鼓励您使用ArrayList因为它是一个成熟的容器。但是,按照AbstractList实施equals()似乎只有好处。 始终需要==来确定两个引用是否为同一对象。

Java 数组有点不寻常,因为它们可能包含原语,但这似乎不是一个太大的障碍。

这些数组相等吗?

Integer objects[]={Integer.valueOf(1),Integer.valueOf(1000)};
int integers[]={1,1000}; 

我会选择"不"作为最一致的。但如果不是,你会得到潜在的令人惊讶的语义,这些对象将不相等:

int ai[]={1,2,3}; 
long al[]={1,2,3};

也许没有人真正考虑过它,改变这样基本的东西肯定会有一些密码破译的后果。

最新更新