문자열 객체와 문자열 리터럴의 차이점
이 질문에는 이미 답변이 있습니다.
차이점은 무엇입니까
String str = new String("abc");
과
String str = "abc";
당신이 사용하는 경우 문자열 리터럴 문자열이 될 수 구금 ,하지만 당신은 사용할 때 new String("...")
새 문자열 개체를 가져옵니다.
이 예제에서 두 문자열 리터럴은 동일한 객체를 참조합니다.
String a = "abc";
String b = "abc";
System.out.println(a == b); // true
여기에 2 개의 서로 다른 객체가 만들어지고 다른 참조가 있습니다.
String c = new String("abc");
String d = new String("abc");
System.out.println(c == d); // false
일반적으로 가능하면 문자열 리터럴 표기법을 사용해야합니다. 읽기 쉽고 컴파일러가 코드 를 최적화 할 수 있는 기회를 제공 합니다.
문자열 리터럴 자바 언어 개념이다. 이것은 문자열 리터럴입니다.
"a String literal"
문자열 객체 의 개별 인스턴스 java.lang.String
클래스입니다.
String s1 = "abcde";
String s2 = new String("abcde");
String s3 = "abcde";
모두 유효하지만 약간의 차이가 있습니다. 내부 문자열 객체를 s1
참조 합니다. 이는 문자 순서 가 중앙 위치에 저장되고 동일한 리터럴 이 다시 사용될 때마다 JVM이 새 문자열 오브젝트를 작성하지 않고 캐시 된 문자열 의 참조를 사용함을 의미합니다 ."abcde"
"abcde"
s2
새로운 String 객체 로 보장 되므로이 경우에는 다음과 같습니다.
s1 == s2 // is false
s1 == s3 // is true
s1.equals(s2) // is true
긴 답변은 여기 에서 확인할 수 있으므로 짧은 답변을 드리겠습니다.
이렇게하면 :
String str = "abc";
String 에서 intern()
메소드를 호출하고 있습니다. 이 방법 은 내부 객체 풀 을 참조 합니다. 호출 한 문자열이 이미 풀에 있으면 해당 참조 가에 할당됩니다 . 그렇지 않은 경우 새 풀에 배치되고 이에 대한 참조가에 할당됩니다 .String
intern()
String
str
String
str
다음 코드가 주어진다 :
String str = "abc";
String str2 = "abc";
boolean identity = str == str2;
당신이 수행하여 개체의 신원을 확인하는 경우 ==
(당신이 말 그대로 요구하고있다 :이 두 참조가 동일한 개체를 가리 할), 당신은 얻을 true
.
그러나, 당신은하지 않습니다 필요 로 intern()
Strings
. 다음 Object
을 수행하여 힙에 새로 작성하도록 할 수 있습니다 .
String str = new String("abc");
String str2 = new String("abc");
boolean identity = str == str2;
이 경우, str
그리고 str2
다른에 대한 참조 Objects
된 어느 것도, 구금 당신이 테스트 할 때 그래서, Object
사용 정체성 ==
, 당신이 얻을 것이다은 false
.
실제로 코딩 좋은 측면에서 : 할 수 없습니다 사용하는 ==
문자열 어떤지를 확인하기 위해 사용하는 .equals()
대신.
문자열을 변경할 수 없으므로 다음을 수행하십시오.
String a = "xyz"
문자열을 만드는 동안, 스트링의 풀에서 JVM 검색 이미 문자열 값이 존재하는 경우 "xyz"
만약 그렇다면, 'a'
단순히 해당 문자열의 참조가 될 것이며, 새로운 String 객체가 만들어지지 않습니다.
그러나 당신이 말한다면 :
String a = new String("xyz")
풀에있는 String
경우에도 JVM이 새 참조 를 작성하도록 "xyz"
합니다.
자세한 내용은 이것을 읽으십시오 .
"abc"
리터럴 문자열입니다.
Java에서 이러한 리터럴 문자열은 내부적으로 풀링 "abc"
되며 코드에서 선언 된 해당 문자열 리터럴이있는 경우 동일한 String 인스턴스 가 사용됩니다. "abc" == "abc"
둘 다 동일한 String 인스턴스 이므로 항상 사실입니다.
이 String.intern()
방법을 사용하면 내부적으로 풀링 된 문자열에 원하는 문자열을 추가 할 수 있습니다.이 문자열은 java가 종료 될 때까지 메모리에 보관됩니다.
반면에를 사용 new String("abc")
하면 논리적으로 "abc"
리터럴 과 동일한 새 문자열 객체가 메모리에 생성됩니다 . "abc" == new String("abc")
논리적으로 동일하지만 서로 다른 인스턴스를 참조하는 것처럼 항상 거짓입니다.
문자열 리터럴 주위에 문자열 생성자를 감싸는 것은 가치가 없으며 필요한 것보다 더 많은 메모리를 불필요하게 사용합니다.
문자열은 다른 프로그래밍 언어와 다른 Java 클래스입니다. 모든 클래스에서 객체 선언과 초기화는
String st1 = new String();
또는
String st2 = new String("Hello");
String st3 = new String("Hello");
여기에 st1
, st2
그리고 st3
다른 개체입니다.
그건:
st1 == st2 // false
st1 == st3 // false
st2 == st3 // false
왜냐하면 st1
, st2
, st3
3 명 가지 목적 및 참조하는 ==
메모리 위치에 평등, 따라서 결과를 확인한다.
그러나:
st1.equals(st2) // false
st2.equals(st3) // true
이곳까지 .equals()
콘텐츠에 대한 검사 방법 및 내용 st1 = ""
, st2 = "hello"
및 st3 = "hello"
. 따라서 결과.
그리고 String 선언의 경우
String st = "hello";
여기서 클래스의 intern()
메소드 String
가 호출 "hello"
되어 인턴 풀에 있는지 확인 하고, 그렇지 않은 경우 인턴 풀에 추가되고 "hello"가 인턴 풀에 존재 st
하면 기존의 메모리를 가리 킵니다 "hello"
.
따라서 다음의 경우 :
String st3 = "hello";
String st4 = "hello";
여기:
st3 == st4 // true
때문에 st3
와 st4
같은 메모리 주소를 가리키는.
또한:
st3.equals(st4); // true as usual
첫 번째 경우에는 두 개의 객체가 생성됩니다.
두 번째 경우는 단지 하나입니다.
두 가지 방법 모두 str
를 언급 하지만 "abc"
.
일부 분해는 항상 흥미 롭습니다 ...
$ cat Test.java
public class Test {
public static void main(String... args) {
String abc = "abc";
String def = new String("def");
}
}
$ javap -c -v Test
Compiled from "Test.java"
public class Test extends java.lang.Object
SourceFile: "Test.java"
minor version: 0
major version: 50
Constant pool:
const #1 = Method #7.#16; // java/lang/Object."<init>":()V
const #2 = String #17; // abc
const #3 = class #18; // java/lang/String
const #4 = String #19; // def
const #5 = Method #3.#20; // java/lang/String."<init>":(Ljava/lang/String;)V
const #6 = class #21; // Test
const #7 = class #22; // java/lang/Object
const #8 = Asciz <init>;
...
{
public Test(); ...
public static void main(java.lang.String[]);
Code:
Stack=3, Locals=3, Args_size=1
0: ldc #2; // Load string constant "abc"
2: astore_1 // Store top of stack onto local variable 1
3: new #3; // class java/lang/String
6: dup // duplicate top of stack
7: ldc #4; // Load string constant "def"
9: invokespecial #5; // Invoke constructor
12: astore_2 // Store top of stack onto local variable 2
13: return
}
이미 게시 된 답변 외에도 javaranch에 대한 이 훌륭한 기사를 참조하십시오 .
String 클래스 문서 에 따르면 동일합니다.
에 대한 설명서 String(String original)
: 또한이 말한다 원래의 명시적인 카피가 필요하지 않은 문자열은 불변이므로,이 생성자의 사용이 불필요합니다.
Java 문서가 오도하는 것처럼 보이기 때문에 다른 응답을 찾으십시오.
다음은 몇 가지 비교입니다.
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
System.out.println(s1 == s2); //true
System.out.println(s1.equals(s2)); //true
System.out.println(s1 == s3); //false
System.out.println(s1.equals(s3)); //true
s3 = s3.intern();
System.out.println(s1 == s3); //true
System.out.println(s1.equals(s3)); //true
때 intern()
호출되는 기준이 변경됩니다.
String 객체와 문자열 리터럴 사이에는 미묘한 차이가 있습니다.
String s = "abc"; // creates one String object and one reference variable
이 간단한 경우 " abc "는 풀에 들어가고 s 는이를 참조합니다.
String s = new String("abc"); // creates two objects,and one reference variable
이 경우 new
키워드를 사용했기 때문에 Java는 일반 (풀이 아닌) 메모리에 새 String 객체를 만들고 s에서 참조합니다. 또한 리터럴 " abc "가 풀에 배치됩니다.
String s = new String("FFFF")
"FFFF"
문자열 String
을 가리키는 문자열과 객체라는 2 개의 객체를 만듭니다. "FFFF"
따라서 포인터에 대한 포인터와 같습니다 (참조에 대한 언급, 용어에 관심이 없습니다).
절대 사용해서는 안된다고합니다 new String("FFFF")
참고 URL : https://stackoverflow.com/questions/3297867/difference-between-string-object-and-string-literal
'Programing' 카테고리의 다른 글
MySQL 및 GROUP_CONCAT () 최대 길이 (0) | 2020.04.12 |
---|---|
HTML5 data- * with asp.net mvc TextboxFor HTML 속성 (0) | 2020.04.12 |
연결이 닫힌 후에도 JDBC 결과 세트와 명령문을 별도로 닫아야합니까? (0) | 2020.04.12 |
PostgreSQL에서 UPSERT (MERGE, INSERT ... ON DUPLICATE UPDATE)하는 방법은 무엇입니까? (0) | 2020.04.12 |
추적되지 않은 파일에 git diff를 사용할 수 있습니까? (0) | 2020.04.12 |