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
中的方法。