==
또는 !=
이 아닌 equals()
메서드로 비교해야 합니다.==
또는 !=
을 사용하는데 이 연산자는 두 개체의 값이 아닌 참조를 비교합니다. 두 참조가 같지 않을 가능성이 큽니다.
if (args[0] == STRING_CONSTANT) {
logger.info("miracle");
}
==
및 !=
연산자는 같은 개체에 포함된 문자열을 비교하도록 사용할 때에만 예상대로 작동합니다. 이를 위한 가장 일반적인 방법은 인턴(intern)된 문자열에 대한 것이고, 여기에서 이 문자열은 String
클래스에 의해 유지되는 개체의 풀에 추가할 수 있습니다. 한 번 문자열이 인턴(intern)되면, 모든 문자열 사용은 동일한 개체를 사용하고 같은 연산자가 예상대로 작동합니다. 모든 문자열 리터럴 및 문자열 값 상수는 자동으로 인턴(intern)됩니다. 다른 문자열은 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
또는 RegularUser
클래스가 아닌 user
인스턴스에 대해 getAccessLevel()
메서드를 호출하므로 이 조건에서는 항상 true
가 반환됩니다. 그리고 이 if/else
블록 부분으로 진입하기 위해 instanceof
를 사용했더라도 제한된 작업이 수행됩니다.
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
배열에서 지정하여 클래스에 대해 Serializable 필드를 수동으로 정의할 수 있습니다. 이 기능은 serialPersistentFields
가 private
, static
및 final
로 선언된 경우에만 작동합니다.serialPersistentFields
선언은 private
, static
및 final
이 아니기 때문에 Serializable
필드를 정의하는 데 사용되지 않습니다.
class List implements Serializable {
public ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("myField", List.class) };
...
}
java.util.Arrays.equals().
대신 배열에 대해 Object.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
의 메서드는 호출되지 않습니다.