2014-09-20 1 views
0

String의 intern 메서드를 이해합니다. (s1 == s4)Java에서 String intern 메서드를 사용할 때 생성되는 객체 수

String s1 = "Hello";    
String s4 = new String("Hello").intern(); 

출력은 거짓 우리가 intern를 사용하지 않은 것, 사실 될 것입니다.

제 질문은 위의 두 문장을 실행하는 것입니다, 얼마나 많은 객체가 생성됩니까 ?? 하나 또는 둘? 새로운 연산자가 하나 이상의 개체를 추가합니까?

나는 String s4 = new String("Hello")이 두 개의 객체를 만들지 만, intern과 혼동하는 것을 알고 있습니다.

+0

두 번째 줄 끝의'.intern()'은 [this]와 다릅니다. (http://stackoverflow.com/questions/10045147/how-many-objects-are- 생성되는? rq = 1), [this] (http://stackoverflow.com/questions/1881922/questions-about-javas-string-pool) 및 [this] (http : // stackoverflow.com/questions/11180866/얼마나 많은 문자열 개체가 메모리에서 생성됩니까? lq = 1). –

+0

숫자가 2, 3 또는 4 일 수 있기 때문에 약간의 트릭 질문입니다. –

+1

(하지만이 동일한 질문은 이전에 요청한 적이 있습니다. 분명히 표준 인터뷰 질문 일 수도 있고 바보 같은 질문 일 수도 있습니다. 많은 인터뷰 질문이 있습니다.) –

답변

1

String s4 = new String("Hello") 
+0

그러면 위의 인턴의 용도는 무엇입니까? – Anand

+0

인턴과 함께, 문자열 리터럴 "Hello"에 대한 permgen 공간을 조사합니다. 그래서 여기서 인턴으로 아무 것도 얻지 못했습니다. –

+0

@Anand - 인턴은 원래 "Hello"인스턴스를 돌려줍니다. –

0

참조 문자열을 비교하는 빠른 때문에 당신이 당신의 코드를 최적화 할 필요가있을 때 당신은 인턴을 사용해야하기위한

String s1 = "Hello"; 

다른 두

하나가 될 것입니다.

귀하의 진술에 관해서는 두 개체 만 생성됩니다.

인턴을 너무 많이 사용하면 일반적으로 작은 PermGen에 저장되므로 메모리 예외가 발생할 수 있으므로 JVM을 올바르게 구성해야합니다.

+0

'intern'는'intern' 연산 자체가 상당히 비싸기 때문에 동일한 값의 * repeated * 비교에만 유용합니다. –

+1

자바 프로그래밍에서 15 년 동안 나는 intern()가 최적화에 필요한 경우를 본 적이 없다. 그러나 불필요하게 사용되거나 성능이 실제로 악화되는 경우가 있습니다. –

0

... 얼마나 많은 개체가 생성됩니까 ?? 하나 또는 둘?

두. 단 하나만 유지됩니다. 다른 하나는 즉시 가비지 수집 대상입니다.

새 연산자로 하나 이상의 개체가 생성됩니까?

예. 간단히. 그런 다음 .intern 메서드를 호출하고 결과를 저장합니다. 그것의 .intern 메쏘드는 s1이 가르키고있는 동일한 인턴 된 문자열을 반환 할 것이고 따라서 new을 통해 생성 된 객체는 곧바로 GC에 적합합니다. 우리가 바이트 코드를 보면

우리는이를 볼 수 있습니다

 
    public static void main(java.lang.String[]); 
    Code: 
     0: ldc   #2     // String Hello 
     2: astore_1 
     3: new   #3     // class java/lang/String 
     6: dup   
     7: ldc   #2     // String Hello 
     9: invokespecial #4     // Method java/lang/String."":(Ljava/lang/String;)V 
     12: invokevirtual #5     // Method java/lang/String.intern:()Ljava/lang/String; 
     15: astore_2  
     16: getstatic  #6     // Field java/lang/System.out:Ljava/io/PrintStream; 
     19: aload_2  
     20: invokevirtual #7     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
     23: getstatic  #6     // Field java/lang/System.out:Ljava/io/PrintStream; 
     26: aload_1  
     27: aload_2  
     28: if_acmpne  35 
     31: iconst_1  
     32: goto   36 
     35: iconst_0  
     36: invokevirtual #8     // Method java/io/PrintStream.println:(Z)V 
     39: return   

3-9, "Hello"에서 새 String 객체를 생성 스택에의 참조를 떠나, 그리고 우리는 즉시 팝하는 (intern 전화 스택에서 새 문자열을 참조) intern의 반환 값을 s4에 저장합니다. 따라서 임시로 생성 된 객체는 더 이상 참조되지 않습니다.

+0

고맙습니다.하지만 인턴을 사용하면 무엇을 성취 할 수 있습니까? – Anand

+1

@Anand :'someString'이 큰 문자열의 부분 문자열이고 오랫동안 그 문자열을 고정하려고 할 때 사용되는 숙어'new String (someString) .intern()'이 사용되었습니다. Java의 수명이 다할 때'someString = someBigString.substring (10, 20)'을 실행하면'someByString'과'someBigString'은 같은 문자 배열을 참조합니다. 그래서'someBigString'을 해제하면 메모리 누수가 발생합니다 -'someString'은 실제로 사용하지 않은 문자를 참조합니다. 관용구가 그것을 고쳤습니다. 1.7.0_06부터 문자열은 더 이상 char 배열을 공유하지 않습니다. –

+0

@HotLicks : 팔로우 중. 'substring '을 통해 생성 된 문자열은'offset'과'count'를 사용하는 기본 char 배열을 ** 1.7 **로 (특히 위에서 언급 한 1.7.0_06까지) 공유합니다. 1.7.0_05에서 'String.java'의 소스, 특히 1,961과 645 행을 살펴보십시오. 귀하의 의견을 오해해야합니다. –

관련 문제