equals()
方法來比較字串,而不是 ==
或 !=
。==
或 !=
來比較兩個字串是否相等,其為比較兩個物件是否相同,而非它們的值。因此,若使用這個方法,兩個參照將永遠不會相等。
if (args[0] == STRING_CONSTANT) {
logger.info("miracle");
}
==
和 !=
運算子來比較相同物件中的字串時,它們只會如預期般的運作。要出現這種情況,最常見的方法就是將字串控制在內部,這樣,將字串增加到由 String
類別維護的物件池中。一旦將字串控制在內部,每次使用這個字串時都將使用相同的物件,並且相等運算子會如預期般運作。所有字串文字和以字串當作值的常數會自動控制在內部。其他字串可以透過呼叫 String.intern()
來以手動控制在內部,這將會回傳目前字串的標準實例,必要時也會建立一個實例。
class AccessLevel{
public static final int ROOT = 0;
//...
public static final int NONE = 9;
}
//...
class User {
private static int access;
public User(){
access = AccessLevel.ROOT;
}
public static int getAccessLevel(){
return access;
}
//...
}
class RegularUser extends User {
private static int access;
public RegularUser(){
access = AccessLevel.NONE;
}
public static int getAccessLevel(){
return access;
}
public static void escalatePrivilege(){
access = AccessLevel.ROOT;
}
//...
}
//...
class SecureArea {
//...
public static void doRestrictedOperation(User user){
if (user instanceof RegularUser){
if (user.getAccessLevel() == AccessLevel.ROOT){
System.out.println("doing a privileged operation");
}else{
throw new RuntimeException();
}
}
}
}
user
實例 (而不是針對 User
或 RegularUser
類別) 呼叫 getAccessLevel()
方法,因此這將意味著,此狀況一律會傳回 true
,並且會執行限制的操作,即使使用 instanceof
以進入 if/else
區塊的此部分也是如此。
private void writeObject(java.io.ObjectOutputStream out) throws IOException;
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;
private void readObjectNoData() throws ObjectStreamException;
serialPersistentFields
,就必須將其宣告為private
、static
及 final
。serialPersistentFields
陣列中指定類別的可序列化欄位來手動定義這些欄位。這項功能只有在宣告 serialPersistentFields
為 private
、static
以及 final
時才有效。serialPersistentFields
的宣告,來定義 Serializable
欄位,因為欄位不是 private
、static
以及 final
。
class List implements Serializable {
public ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("myField", List.class) };
...
}
Object.equals()
,而不是呼叫 java.util.Arrays.equals().
Object.equals()
是錯誤的,因為這將會檢查陣列的位址是否相等,而不是陣列的元素是否相等,所以通常應該由 java.util.Arrays.equals()
取而代之。 Object.equals()
函數嘗試檢查兩個陣列。
...
int[] arr1 = new int[10];
int[] arr2 = new int[10];
...
if (arr1.equals(arr2)){
//treat arrays as if identical elements
}
...
System.Object.Equals()
:
public boolean Equals(string obj) {
...
}
System.Object.Equals()
需要一個 object
類型的引數,因此將永遠不會呼叫此方法。Object.equals()
:
public boolean equals(Object obj1, Object obj2) {
...
}
Object.equals()
只需要一個引數,因此將永遠不會呼叫 Example 1
中的方法。