簡體   English   中英

為什么.equals()方法不會覆蓋Java中的基元數組?

[英]Why is the .equals() method not overriden for arrays of primitives in 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-devs才能真正回答這個問題。)

在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};

也許沒有人真正想過它,改變那些如此基本的東西肯定會有一些代碼破壞的后果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM