Java를 처음 배우면 다음 코드를 자주 접하게 됩니다.
String str1 = new String("hello"); String str2 = new String("hello"); System.out.println(str1==str2); System.out.println(str1.equals(str2));
4행과 5행의 출력 결과가 왜 다른가요? == 메소드와 같음 메소드의 차이점은 무엇입니까? Java를 처음 배울 때 이 점을 파악하지 못하면 나중에 코드를 작성할 때 낮은 수준의 오류를 범하게 됩니다. 오늘은 == 메소드와 같음 메소드의 차이점에 대해 알아 보겠습니다.
1. 관계 연산자 "=="는 정확히 무엇을 비교하나요?
다음 문장은 "Java 프로그래밍 사고"라는 책에서 발췌한 것입니다.
"관계 연산자는 부울 결과를 생성하고 피연산자의 값을 계산합니다. 관계".
이 문장은 간단해 보이지만, 그래도 주의 깊게 이해해야 합니다. 간단히 말하면 ==는 값이 같은지 비교하는 데 사용됩니다. 몇 가지 예를 살펴보겠습니다.
public class Main { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int n=3; int m=3; System.out.println(n==m); String str = new String("hello"); String str1 = new String("hello"); String str2 = new String("hello"); System.out.println(str1==str2); str1 = str; str2 = str; System.out.println(str1==str2); } }
출력 결과는 true false true
n==m의 결과는 true입니다. 변수 n과 변수 m은 둘 다 3이므로 확실히 동일합니다. 그리고 str1과 str2의 두 비교 결과가 다른 이유는 무엇입니까? 이를 이해하려면 기본 데이터 유형 변수와 기본이 아닌 데이터 유형 변수의 차이점을 이해하면 됩니다.
Java에는 8가지 기본 데이터 유형이 있습니다.
부동 소수점 유형: float(4바이트), double(8바이트)
정수 유형: byte(1바이트) , short(2바이트), int(4바이트), long(8바이트)
문자 유형: char(2바이트)
불리언 유형: boolean(JVM 사양에서는 명확하게 지정하지 않음) 차지하는 공간은 리터럴 값 "true" 및 "false"만 취할 수 있다고만 규정되어 있습니다.
이 8가지 기본 데이터 유형의 변수는 변수가 "값"을 직접 저장하므로 관계가 사용됨 연산자 ==를 사용하여 비교할 때 비교되는 것은 "값" 자체입니다. 부동 소수점 유형과 정수 유형은 모두 부호 있는 유형인 반면 char은 부호 없는 유형입니다(char 유형의 값 범위는 0~2^16-1입니다).
즉, 예:
int n=3;
int m=3;
변수 n과 변수 m 모두 값 "3"을 직접 저장하므로 =와 비교할 때 = 결과는 사실이다.
기본이 아닌 데이터 유형의 변수를 일부 책에서는 참조 유형 변수라고 합니다. 예를 들어, 위의 str1은 참조 유형 변수입니다. 참조 유형 변수는 "값" 자체가 아니라 메모리에 연관된 개체의 주소를 저장합니다. 예를 들어 다음 코드 줄은 다음과 같습니다.
String str1;
이 문장은 현재 어떤 개체와도 연결되지 않은 참조 유형 변수를 선언합니다.
그리고 new String("hello")을 사용하여 객체(String 클래스의 인스턴스라고도 함)를 생성하고 이 객체를 str1에 바인딩합니다.
str1= new String("hello ");
그러면 str1은 객체를 가리킵니다(str1은 여러 곳에서 객체에 대한 참조라고도 합니다). 이때 변수 str1은 자신이 가리키는 객체의 저장 주소를 메모리에 저장합니다. "값" 자체가 아닙니다. 즉, 직접 저장된 문자열 "hello"가 아닙니다. 여기의 참조는 C/C++의 포인터와 매우 유사합니다.
따라서 ==를 사용하여 처음으로 str1과 str2를 비교하면 결과가 false입니다. 따라서 각각 다른 객체를 가리키며, 이는 실제로 저장되는 메모리 주소가 다르다는 것을 의미합니다.
두 번째 비교에서 str1과 str2는 모두 str이 가리키는 객체를 가리키므로 결과는 의심할 여지 없이 참입니다.
2. 같음은 무엇을 비교하나요?
equals 메소드는 기본 클래스 Object의 메소드이므로 Object에서 상속되는 모든 클래스는 이 메소드를 갖습니다. equals 메소드의 역할을 보다 직관적으로 이해하기 위해 Object 클래스의 equals 메소드 구현을 직접 살펴보겠습니다.
이 클래스의 소스 코드 경로는 C:Program FilesJavajdk1.6.0_14의 src.zip의 java.lang 경로 아래 Object.java입니다(개인 jdk 설치 경로에 따라 다름).
다음은 Object 클래스의 equals 메소드 구현입니다.
분명히 Object 클래스에서는 equals 메소드를 사용하여 두 항목을 비교합니다. 두 개체의 참조가 동일한지, 즉 동일한 개체를 가리키는지 여부입니다.
그런데 어떤 친구들은 다시 질문을 할 수도 있는데, 다음 코드의 출력 결과가 왜 사실인가요?
public class Main { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub String str1 = new String("hello"); String str2 = new String("hello"); System.out.println(str1.equals(str2)); } }
정확히 알기 위해서는 String 클래스의 equals 메소드의 구체적인 구현을 살펴보면 됩니다. 또한 이 경로 아래에는 String.java가 String 클래스의 구현입니다.
다음은 String 클래스의 equals 메소드의 구체적인 구현입니다.
String 클래스가 비교를 위해 equals 메소드를 다시 작성하는 것을 볼 수 있습니다. points 문자열 개체에 저장된 문자열이 동일한지 여부입니다.
Double, Date, Integer 등과 같은 일부 다른 클래스는 가리키는 객체에 저장된 내용이 동일한지 비교하기 위해 equals 메서드를 재정의했습니다.
요약:
1) ==의 경우 기본 데이터 유형의 변수에 작용하는 경우 저장된 "값"이 동일한지 직접 비교합니다.
참조 유형의 변수에 작용하는 경우; , 객체의 주소
를 가리키는 포인트를 비교합니다. 2) equals 메소드의 경우, 참고: equals 메소드는 기본 데이터 유형의 변수에 대해 작동할 수 없습니다.
재정의되지 않으면 참조 유형이 비교됩니다. 변수가 가리키는 객체의 주소
String 및 Date와 같은 클래스가 equals 메서드를 재정의하면 가리키는 객체의 내용이 비교됩니다.
Java의 같음 및 ==에 대한 더 많은 기사를 보려면 PHP 중국어에 주목하세요. 그물!