Java에서 낮은 수준의 문자열 비교에 대한 이야기
입문
이것은 낮은 수준의 이야기이다
Java는 당분간 보통과 같이 쉽게 읽을 수 있다.
문자열을 비교한 적이 있다면 먼저 읽을 수 있습니다.
복습(?)
Java에서 문자열 비교를 할 때는 "=="로 비교할 수 없습니다.
String#equals 방법을 사용하세요.public class Test {
public static void main(String[] args) {
String a = "HelloWorld";
String b = "Hello";
b += "World";
System.out.println(a == b); // false
System.out.println(a.equals(b)); // true
}
}
잠시만요. "==" 도 진짜가 돼요. public class Test {
public static void main(String[] args) {
String a = "HelloWorld";
String b = "HelloWorld";
System.out.println(a == b); // true
System.out.println(a.equals(b)); // true
}
}
왜?
"==" 구조
JVM
"=="흔히 주소 위치의 비교라고 불리우니 자세히 살펴보자.
Java에서 "=="는 일반적으로 컴파일할 때 JVM의 명령어로 변환됩니다. 예를 들어 "if_acmpne"또는 "if_acmpeq"입니다.
JVM은 Java 파일을 컴파일할 때 class 파일이 많이 생성되죠?이 class 파일을 해석하고 실행하는 것은 JVM(Java Virtual Machine)입니다.
class 파일은 많은 사람들이 읽을 수 없는 형식이지만 JVM(컴퓨터)에게는 읽기 쉬워졌습니다.
JVM은 여러 개의 간단한 명령을 조합하여 복잡한 프로그램을 실현하기 때문에 JVM에서는 하나의 명령에 불과하지만 대부분의 경우 JVM은 이를 여러 명령으로 변환합니다.
JVM 명령 및 작업 스택
그렇다면'if_acmpne'과'if_acmpeq'는 어떤 명령입니까? 작업 창고에서 두 개를 꺼내서 일치하는지 조사하고 지정한 프로그램의 줄로 이동하는 명령입니다.
창고를 세어...?
JVM은 스택머신이라고 불리며 레지스터를 사용하지 않고 스택이라는 기기를 사용하여 다양한 연산을 수행합니다.
※ 창고...위에 놓인 값어치 중 순서대로 꺼내는 장치(포커의 산패 같은 물건)
작업 스택은 작업 영역과 유사합니다.
사칙 연산 등이 적당하기 때문에 자주 사용된다.
(반폴란드 기법 등)
예를 들어 다음과 같은 메커니즘을 통해 5+12를 계산할 수 있다.
그러나 Java의 작업 스택에는 최대 32bit의 요소가 하나만 있습니다.
※ 32bit=2^32의 수량을 처리할 수 있다는 뜻입니다.
자바로 문자를 표시할 때 작업 스택의 요소 1 개 (= 32bit) 가 소모됩니다.
문자열은 가변 크기입니다.때로는 한 글자를 처리하고, 때로는 이 문장처럼 수백 글자를 처리한다.즉, 조작수 창고 1개 요소 (=32bit) 는 어쨌든 모든 문자를 처리할 수 없다는 것이다.
따라서 문자열을 다른 메모리에 저장하고 이 메모리의 주소 (컴퓨터의 주소) 를 작업수 창고에 저장합니다.이렇게 하면 원소 하나 (=32bit) 를 작업하면 충분하다.
※ 다른 메모리와 이 메모리를 사용하는 작업수 창고의 이미지(0x는 특별한 의미가 없음)
if_acmpeq / if_acmpne
위에서 설명한 바와 같이'if_acmpeq'와'if_acmpeq'는 작업수 창고에서 두 개를 꺼냅니다. 만약 이 두 개가'if_acmpeq'라면,'if_acmpene'에서 같지 않을 때 다른 지정한 줄로 이동합니다.(점프는 흔히 볼 수 있는 GOTO 명령 같은 것들)
즉, "if_acmpeq"를 사용하면 작업수 창고의 주소 수치가 같으면 점프 명령이 발생합니다.
이 페이지의 두 번째 소스 코드 ("잠시만요") 에서 같은 주소에 "Hello World"가 저장되어 있기 때문에true로 표시됩니다.
정말로...
같은 곳에 저장되는 건가요?
맞습니다.
그럼 이거 어때요?
적당히 명명된 것을 용서해 주십시오public class Test {
public static void main(String[] args) {
String a = "HelloWorld";
method1(a);
}
public static void method1(String c) {
String k = "HelloWorld";
System.out.println(k == c);
}
}
정답은'진짜'입니다.
클래스 상수 영역
Java 클래스 파일에는 상수 영역이 있습니다.
이 상수 영역은 컴파일할 때 문자열 등을 주로 저장합니다.마술 번호 또는 마술 문자열 (?)이러한 파일은 상수 영역에 저장되며 JVM이 클래스 파일을 읽을 때 메모리로 읽히고 사용됩니다.
예를 들면System.out.println("Hello Ja! Ja!");
"Hello Ja! Ja!"같아요.등이 상수 영역에 저장되어 문자열을 읽습니다.
또한 자바의 컴파일러는 똑똑하기 때문에 같은 문자열이 두 번 나타나도 이전에 한 번 이상 사용하면 같은 상량 구역에서 읽을 수 있다.
즉, 아까 코드에서 방법이 다르더라도 같은 상수 영역의'Hello World'문자열을 참조하기 때문에 주소가 같다는 것이다.
아까 클래스 파일의 상수 영역은 바이너리로 보면'Hello World'가 잘 저장되어 있어요.
이 페이지의 원본 코드는 일부러 저장 영역을'Hello'와'World'두 부분으로 나누어 문자열을 쓴다.
Java의 컴파일러는 그 정도까지는 계산하지 못할 것 같습니다.C의 컴파일러 등도 이곳에 자주 온다.
이퀄스는요?
String 클래스에서 덮어쓰는 것은 내용을 잘 비교하는 코드이다
인상 코드는 다음과 같다.원문은 엄마가 아니다.@Override
public boolean equals(String str) {
if(this.length() != str.length()) {
return false;
}
for(int i = 0; i < str.length(); i++) {
if(this.charAt(i) != str.charAt(i)) { //charAtで任意のn文字目をとりだせる
return false;
}
}
return true;
}
선형으로 앞부터 순서대로 문자를 비교한다.
한 글자는 32bit에 수용할 수 있기 때문에 문제없다.
총결산
문자열을 비교할 때 equals 방법을 사용하세요.
"=="는 진짜일 때 같은 곳에 저장된다.음~음.
내일 행사 달력 보도도 잘 부탁드립니다.
정적 정보 LT 대회 Advent Calendar 2019
Reference
이 문제에 관하여(Java에서 낮은 수준의 문자열 비교에 대한 이야기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yuratwc/items/13f7cf6ca0dcd2536304
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Java에서 문자열 비교를 할 때는 "=="로 비교할 수 없습니다.
String#equals 방법을 사용하세요.
public class Test {
public static void main(String[] args) {
String a = "HelloWorld";
String b = "Hello";
b += "World";
System.out.println(a == b); // false
System.out.println(a.equals(b)); // true
}
}
잠시만요. "==" 도 진짜가 돼요. public class Test {
public static void main(String[] args) {
String a = "HelloWorld";
String b = "HelloWorld";
System.out.println(a == b); // true
System.out.println(a.equals(b)); // true
}
}
왜?
"==" 구조
JVM
"=="흔히 주소 위치의 비교라고 불리우니 자세히 살펴보자.
Java에서 "=="는 일반적으로 컴파일할 때 JVM의 명령어로 변환됩니다. 예를 들어 "if_acmpne"또는 "if_acmpeq"입니다.
JVM은 Java 파일을 컴파일할 때 class 파일이 많이 생성되죠?이 class 파일을 해석하고 실행하는 것은 JVM(Java Virtual Machine)입니다.
class 파일은 많은 사람들이 읽을 수 없는 형식이지만 JVM(컴퓨터)에게는 읽기 쉬워졌습니다.
JVM은 여러 개의 간단한 명령을 조합하여 복잡한 프로그램을 실현하기 때문에 JVM에서는 하나의 명령에 불과하지만 대부분의 경우 JVM은 이를 여러 명령으로 변환합니다.
JVM 명령 및 작업 스택
그렇다면'if_acmpne'과'if_acmpeq'는 어떤 명령입니까? 작업 창고에서 두 개를 꺼내서 일치하는지 조사하고 지정한 프로그램의 줄로 이동하는 명령입니다.
창고를 세어...?
JVM은 스택머신이라고 불리며 레지스터를 사용하지 않고 스택이라는 기기를 사용하여 다양한 연산을 수행합니다.
※ 창고...위에 놓인 값어치 중 순서대로 꺼내는 장치(포커의 산패 같은 물건)
작업 스택은 작업 영역과 유사합니다.
사칙 연산 등이 적당하기 때문에 자주 사용된다.
(반폴란드 기법 등)
예를 들어 다음과 같은 메커니즘을 통해 5+12를 계산할 수 있다.
그러나 Java의 작업 스택에는 최대 32bit의 요소가 하나만 있습니다.
※ 32bit=2^32의 수량을 처리할 수 있다는 뜻입니다.
자바로 문자를 표시할 때 작업 스택의 요소 1 개 (= 32bit) 가 소모됩니다.
문자열은 가변 크기입니다.때로는 한 글자를 처리하고, 때로는 이 문장처럼 수백 글자를 처리한다.즉, 조작수 창고 1개 요소 (=32bit) 는 어쨌든 모든 문자를 처리할 수 없다는 것이다.
따라서 문자열을 다른 메모리에 저장하고 이 메모리의 주소 (컴퓨터의 주소) 를 작업수 창고에 저장합니다.이렇게 하면 원소 하나 (=32bit) 를 작업하면 충분하다.
※ 다른 메모리와 이 메모리를 사용하는 작업수 창고의 이미지(0x는 특별한 의미가 없음)
if_acmpeq / if_acmpne
위에서 설명한 바와 같이'if_acmpeq'와'if_acmpeq'는 작업수 창고에서 두 개를 꺼냅니다. 만약 이 두 개가'if_acmpeq'라면,'if_acmpene'에서 같지 않을 때 다른 지정한 줄로 이동합니다.(점프는 흔히 볼 수 있는 GOTO 명령 같은 것들)
즉, "if_acmpeq"를 사용하면 작업수 창고의 주소 수치가 같으면 점프 명령이 발생합니다.
이 페이지의 두 번째 소스 코드 ("잠시만요") 에서 같은 주소에 "Hello World"가 저장되어 있기 때문에true로 표시됩니다.
정말로...
같은 곳에 저장되는 건가요?
맞습니다.
그럼 이거 어때요?
적당히 명명된 것을 용서해 주십시오public class Test {
public static void main(String[] args) {
String a = "HelloWorld";
method1(a);
}
public static void method1(String c) {
String k = "HelloWorld";
System.out.println(k == c);
}
}
정답은'진짜'입니다.
클래스 상수 영역
Java 클래스 파일에는 상수 영역이 있습니다.
이 상수 영역은 컴파일할 때 문자열 등을 주로 저장합니다.마술 번호 또는 마술 문자열 (?)이러한 파일은 상수 영역에 저장되며 JVM이 클래스 파일을 읽을 때 메모리로 읽히고 사용됩니다.
예를 들면System.out.println("Hello Ja! Ja!");
"Hello Ja! Ja!"같아요.등이 상수 영역에 저장되어 문자열을 읽습니다.
또한 자바의 컴파일러는 똑똑하기 때문에 같은 문자열이 두 번 나타나도 이전에 한 번 이상 사용하면 같은 상량 구역에서 읽을 수 있다.
즉, 아까 코드에서 방법이 다르더라도 같은 상수 영역의'Hello World'문자열을 참조하기 때문에 주소가 같다는 것이다.
아까 클래스 파일의 상수 영역은 바이너리로 보면'Hello World'가 잘 저장되어 있어요.
이 페이지의 원본 코드는 일부러 저장 영역을'Hello'와'World'두 부분으로 나누어 문자열을 쓴다.
Java의 컴파일러는 그 정도까지는 계산하지 못할 것 같습니다.C의 컴파일러 등도 이곳에 자주 온다.
이퀄스는요?
String 클래스에서 덮어쓰는 것은 내용을 잘 비교하는 코드이다
인상 코드는 다음과 같다.원문은 엄마가 아니다.@Override
public boolean equals(String str) {
if(this.length() != str.length()) {
return false;
}
for(int i = 0; i < str.length(); i++) {
if(this.charAt(i) != str.charAt(i)) { //charAtで任意のn文字目をとりだせる
return false;
}
}
return true;
}
선형으로 앞부터 순서대로 문자를 비교한다.
한 글자는 32bit에 수용할 수 있기 때문에 문제없다.
총결산
문자열을 비교할 때 equals 방법을 사용하세요.
"=="는 진짜일 때 같은 곳에 저장된다.음~음.
내일 행사 달력 보도도 잘 부탁드립니다.
정적 정보 LT 대회 Advent Calendar 2019
Reference
이 문제에 관하여(Java에서 낮은 수준의 문자열 비교에 대한 이야기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yuratwc/items/13f7cf6ca0dcd2536304
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
public class Test {
public static void main(String[] args) {
String a = "HelloWorld";
String b = "HelloWorld";
System.out.println(a == b); // true
System.out.println(a.equals(b)); // true
}
}
JVM
"=="흔히 주소 위치의 비교라고 불리우니 자세히 살펴보자.
Java에서 "=="는 일반적으로 컴파일할 때 JVM의 명령어로 변환됩니다. 예를 들어 "if_acmpne"또는 "if_acmpeq"입니다.
JVM은 Java 파일을 컴파일할 때 class 파일이 많이 생성되죠?이 class 파일을 해석하고 실행하는 것은 JVM(Java Virtual Machine)입니다.
class 파일은 많은 사람들이 읽을 수 없는 형식이지만 JVM(컴퓨터)에게는 읽기 쉬워졌습니다.
JVM은 여러 개의 간단한 명령을 조합하여 복잡한 프로그램을 실현하기 때문에 JVM에서는 하나의 명령에 불과하지만 대부분의 경우 JVM은 이를 여러 명령으로 변환합니다.
JVM 명령 및 작업 스택
그렇다면'if_acmpne'과'if_acmpeq'는 어떤 명령입니까? 작업 창고에서 두 개를 꺼내서 일치하는지 조사하고 지정한 프로그램의 줄로 이동하는 명령입니다.
창고를 세어...?
JVM은 스택머신이라고 불리며 레지스터를 사용하지 않고 스택이라는 기기를 사용하여 다양한 연산을 수행합니다.
※ 창고...위에 놓인 값어치 중 순서대로 꺼내는 장치(포커의 산패 같은 물건)
작업 스택은 작업 영역과 유사합니다.
사칙 연산 등이 적당하기 때문에 자주 사용된다.
(반폴란드 기법 등)
예를 들어 다음과 같은 메커니즘을 통해 5+12를 계산할 수 있다.
그러나 Java의 작업 스택에는 최대 32bit의 요소가 하나만 있습니다.
※ 32bit=2^32의 수량을 처리할 수 있다는 뜻입니다.
자바로 문자를 표시할 때 작업 스택의 요소 1 개 (= 32bit) 가 소모됩니다.
문자열은 가변 크기입니다.때로는 한 글자를 처리하고, 때로는 이 문장처럼 수백 글자를 처리한다.즉, 조작수 창고 1개 요소 (=32bit) 는 어쨌든 모든 문자를 처리할 수 없다는 것이다.
따라서 문자열을 다른 메모리에 저장하고 이 메모리의 주소 (컴퓨터의 주소) 를 작업수 창고에 저장합니다.이렇게 하면 원소 하나 (=32bit) 를 작업하면 충분하다.
※ 다른 메모리와 이 메모리를 사용하는 작업수 창고의 이미지(0x는 특별한 의미가 없음)
if_acmpeq / if_acmpne
위에서 설명한 바와 같이'if_acmpeq'와'if_acmpeq'는 작업수 창고에서 두 개를 꺼냅니다. 만약 이 두 개가'if_acmpeq'라면,'if_acmpene'에서 같지 않을 때 다른 지정한 줄로 이동합니다.(점프는 흔히 볼 수 있는 GOTO 명령 같은 것들)
즉, "if_acmpeq"를 사용하면 작업수 창고의 주소 수치가 같으면 점프 명령이 발생합니다.
이 페이지의 두 번째 소스 코드 ("잠시만요") 에서 같은 주소에 "Hello World"가 저장되어 있기 때문에true로 표시됩니다.
정말로...
같은 곳에 저장되는 건가요?
맞습니다.
그럼 이거 어때요?
적당히 명명된 것을 용서해 주십시오public class Test {
public static void main(String[] args) {
String a = "HelloWorld";
method1(a);
}
public static void method1(String c) {
String k = "HelloWorld";
System.out.println(k == c);
}
}
정답은'진짜'입니다.
클래스 상수 영역
Java 클래스 파일에는 상수 영역이 있습니다.
이 상수 영역은 컴파일할 때 문자열 등을 주로 저장합니다.마술 번호 또는 마술 문자열 (?)이러한 파일은 상수 영역에 저장되며 JVM이 클래스 파일을 읽을 때 메모리로 읽히고 사용됩니다.
예를 들면System.out.println("Hello Ja! Ja!");
"Hello Ja! Ja!"같아요.등이 상수 영역에 저장되어 문자열을 읽습니다.
또한 자바의 컴파일러는 똑똑하기 때문에 같은 문자열이 두 번 나타나도 이전에 한 번 이상 사용하면 같은 상량 구역에서 읽을 수 있다.
즉, 아까 코드에서 방법이 다르더라도 같은 상수 영역의'Hello World'문자열을 참조하기 때문에 주소가 같다는 것이다.
아까 클래스 파일의 상수 영역은 바이너리로 보면'Hello World'가 잘 저장되어 있어요.
이 페이지의 원본 코드는 일부러 저장 영역을'Hello'와'World'두 부분으로 나누어 문자열을 쓴다.
Java의 컴파일러는 그 정도까지는 계산하지 못할 것 같습니다.C의 컴파일러 등도 이곳에 자주 온다.
이퀄스는요?
String 클래스에서 덮어쓰는 것은 내용을 잘 비교하는 코드이다
인상 코드는 다음과 같다.원문은 엄마가 아니다.@Override
public boolean equals(String str) {
if(this.length() != str.length()) {
return false;
}
for(int i = 0; i < str.length(); i++) {
if(this.charAt(i) != str.charAt(i)) { //charAtで任意のn文字目をとりだせる
return false;
}
}
return true;
}
선형으로 앞부터 순서대로 문자를 비교한다.
한 글자는 32bit에 수용할 수 있기 때문에 문제없다.
총결산
문자열을 비교할 때 equals 방법을 사용하세요.
"=="는 진짜일 때 같은 곳에 저장된다.음~음.
내일 행사 달력 보도도 잘 부탁드립니다.
정적 정보 LT 대회 Advent Calendar 2019
Reference
이 문제에 관하여(Java에서 낮은 수준의 문자열 비교에 대한 이야기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yuratwc/items/13f7cf6ca0dcd2536304
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
public class Test {
public static void main(String[] args) {
String a = "HelloWorld";
method1(a);
}
public static void method1(String c) {
String k = "HelloWorld";
System.out.println(k == c);
}
}
System.out.println("Hello Ja! Ja!");
@Override
public boolean equals(String str) {
if(this.length() != str.length()) {
return false;
}
for(int i = 0; i < str.length(); i++) {
if(this.charAt(i) != str.charAt(i)) { //charAtで任意のn文字目をとりだせる
return false;
}
}
return true;
}
문자열을 비교할 때 equals 방법을 사용하세요.
"=="는 진짜일 때 같은 곳에 저장된다.음~음.
내일 행사 달력 보도도 잘 부탁드립니다.
정적 정보 LT 대회 Advent Calendar 2019
Reference
이 문제에 관하여(Java에서 낮은 수준의 문자열 비교에 대한 이야기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/yuratwc/items/13f7cf6ca0dcd2536304텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)