String 상수 탱크 상세 설명

한 블 로그 에서 본 6 개의 문 제 를 먼저 보 세 요. 다 알 면 이 부분의 지식 을 잘 습득 할 수 있 습 니 다!출력 결 과 는 코드 설명 뒤에 있 습 니 다:
test1:
package StringTest;

public class test1 {

    /**
     * @param args
     */
    public static void main(String[] args){
        String a = "a1";
        String b = "a"+ 1;
        System.out.println(a==b);
    }//true

}

test2:
package StringTest;

public class test2 {

    /**
     * @param args
     */
    public static void main(String[] args){
        String a = "ab";
        String bb = "b";
        String b = "a"+ bb;    //          
        System.out.println(a==b);
    }//false

}

test3:
package StringTest;

public class test3 {

    /**
     * @param args
     */
    public static void main(String[] args){
        String a = "ab";
        final String bb = "b";
        String b = "a"+ bb;    //bb final    ,        b
        System.out.println(a==b);
    }//true

}

test4:
package StringTest;

public class test4 {

    /**
     * @param args
     */
    public static void main(String[] args){
        String a = "ab";
        final String bb = getBB();
        String b = "a"+ bb;//bb        ,      final ,        ,        bb  
        System.out.println(a==b);
    }//false
    private static String getBB(){ return "b"; }

}

test5:
package StringTest;

public class test5 {

    /**
     * @param args
     */
    private static String a = "ab";
    public static void main(String[] args){
        String s1 = "a";
        String s2 = "b";
        String s = s1 + s2;//+   
        System.out.println(s == a);
        System.out.println(s.intern() == a);//intern   
    }//flase true

}

test6:
package StringTest;

public class test6 {

    /**
     * @param args
     */
    private static String a = new String("ab");
    public static void main(String[] args){
        String s1 = "a";
        String s2 = "b";
        String s = s1 + s2;
        System.out.println(s == a);
        System.out.println(s.intern() == a);
        System.out.println(s.intern() == a.intern());
    }//flase false true
}

1. String 은 private final char value [] 를 사용 하여 문자열 의 저장 을 실현 합 니 다. 즉, String 대상 이 생 성 된 후에 이 대상 에 저 장 된 문자열 내용 을 다시 수정 할 수 없습니다.그 렇 기 때문에 String 타 입 은 가 변 적 이지 않다 (immutable).String 클래스 는 "" 따옴표 "를 사용 하여 만 드 는 특별한 방법 이 있 습 니 다. 예 를 들 어 new String (" i am ") 은 실제 2 개의 String 대상 을 만 들 었 습 니 다. 하 나 는" i am "이" "따옴표" 를 통 해 만 들 었 고 다른 하 나 는 new 를 통 해 만 들 었 습 니 다. 다만 그들 이 만 든 시기 가 다 릅 니 다. 하 나 는 컴 파일 기간 이 고 하 나 는 실행 기간 입 니 다!java 는 String 형식 에 + 연산 자 를 다시 불 러 왔 습 니 다. 두 문자열 을 직접 + 로 연결 할 수 있 습 니 다.런 타임 에 String 클래스 를 호출 하 는 intern () 방법 은 String Pool 에 대상 을 동적 으로 추가 할 수 있 습 니 다.예 1 String s1 = "sss 111";/ / 이 문 구 는 위의 String s2 = "sss 111" 과 같 습 니 다.  System.out.println(s1 == s2); //결 과 는 true 예 2 String s1 = new String ("sss 111") 입 니 다.  String s2 = "sss111";   System.out.println(s1 == s2); //결 과 는 false 예 3 String s1 = new String ("sss 111") 입 니 다.  s1 = s1.intern();   String s2 = "sss111";   System.out.println(s1 == s2);//결 과 는 true 예 4 String s1 = new String ("111");  String s2 = "sss111";   String s3 = "sss" + "111";   String s4 = "sss" + s1;   System.out.println(s2 == s3); //true   System.out.println(s2 == s4); //false   System.out.println(s2 == s4.intern()); //true 결 과 는 다음 과 같이 분석 되 었 습 니 다. 1. 따옴표 로 만 든 문자열 은 모두 상수 이 고 컴 파일 기간 은 String Pool 에 저 장 된 것 이 확실 합 니 다.2. new String (") 을 사용 하여 만 든 대상 은 힙 에 저 장 됩 니 다. 실행 기간 에 새로 만 든 것 입 니 다.3. "aa" + "aa" 와 같은 상수 만 포함 하 는 문자열 연결 부 호 를 사용 하여 만 든 것 도 상수 입 니 다. 컴 파일 기간 이 확정 되 고 String Pool 에 저장 되 었 습 니 다.4. 변 수 를 포함 하 는 문자열 연결 부 호 를 사용 합 니 다. 예 를 들 어 "aa" + s1 이 만 든 대상 은 실행 기간 에 만 들 어 졌 고 힙 에 저 장 됩 니 다.자주 보 는 면접 문제 도 몇 개 있 습 니 다. String s1 = new String ("s1");  String s2 = new String("s1") ; 위 에 String 대상 을 몇 개 만 들 었 습 니까?정 답: 3 개, 컴 파일 기간 Constant Pool 에 1 개 를 만 들 고, 실행 기간 힙 에 2 개 를 만 듭 니 다. (new 로 만 든 new 는 한 번 에 하나의 대상 을 만 듭 니 다. 따옴표 로 만 든 것 은 상수 풀 에 있 으 면 바로 가리 키 며, 만 들 지 않 아 도 됩 니 다) String s1 = "s1";  String s2 = s1;   s2 = "s2"; s1 이 가리 키 는 대상 의 문자열 은 무엇 입 니까?정 답: "s1".(String 가 변 하지 않 는, s2 = "s2" 를 영원히 잊 지 마 세 요. 실제로 s2 의 지향 은 변 했 습 니 다. 왜냐하면 당신 은 하나의 String 을 바 꿀 수 없 기 때 문 입 니 다.)사용 가능: String str = new String ("abc");String str = "abc"; 두 가지 형식 으로 만 듭 니 다. 첫 번 째 는 new () 로 새 대상 을 만 듭 니 다. 쌓 여 있 습 니 다.호출 할 때마다 새로운 대상 을 만 듭 니 다.두 번 째 는 스 택 에 String 류 의 대상 참조 변수 str 를 만 든 다음 에 기호 참조 로 문자열 상수 탱크 에 'abc' 가 있 는 지 찾 습 니 다. 없 으 면 'abc' 를 문자열 상수 탱크 에 저장 하고 str 를 'abc' 로 가리 키 며 'abc' 가 있 으 면 str 를 'abc' 로 가리 키 도록 합 니 다.클래스 안의 수치 가 같 는 지 비교 할 때 equals () 방법 을 사용 합 니 다.두 포장 류 의 인용 이 같은 대상 을 가리 키 는 지 테스트 할 때 =, 아래 는 예 를 들 어 위의 이론 을 설명 한다.String str1 = "abc"; String str2 = "abc"; System.out.println(str1==str2); //true 는 str 1 과 str 2 가 같은 대상 을 가리 키 는 것 을 알 수 있다.String str1 =new String ("abc"); String str2 =new String ("abc"); System.out.println(str1==str2); // false 는 new 방식 으로 다른 대상 을 만 드 는 것 입 니 다.매번 하나씩 생 성 된다.따라서 두 번 째 방식 으로 여러 개의 "abc" 문자열 을 만 듭 니 다. 메모리 에 하나의 대상 만 존재 합 니 다. 이러한 쓰기 방법 은 메모리 공간 을 절약 하 는 데 유리 합 니 다. 또한 프로그램의 운행 속 도 를 어느 정도 향상 시 킬 수 있 습 니 다. JVM 은 스 택 에 있 는 데이터 의 실제 상황 에 따라 새로운 대상 을 만 들 필요 가 있 는 지 여 부 를 자동 으로 결정 하기 때 문 입 니 다.String str = new String ("abc");의 코드 는 문자열 값 이 같 든 그렇지 않 든 모두 더미 에 새 대상 을 만 들 고 프로그램의 부담 을 가중 시 킵 니 다.다른 한편, 주의해 야 할 것 은 String str = "abc" 와 같은 것 을 사용 하고 있 습 니 다.의 형식 정의 클래스 는 항상 당연히 String 클래스 의 대상 str 를 만 들 었 다 고 생각 합 니 다.함정 이 걱정 이 야!대상 이 생 성 되 지 않 았 을 수도 있 습 니 다!이전에 만 든 대상 을 가리 키 는 것 일 수도 있 습 니 다.new () 방법 을 통 해서 만 매번 새로운 대상 을 만 들 수 있 습 니 다.String 류 의 immutable 성질 때문에 String 변수 가 값 을 자주 바 꿔 야 할 때 StringBuffer 류 를 사용 하여 프로그램 효율 을 높이 는 것 을 고려 해 야 합 니 다.1. 우선 String 은 8 가지 기본 데이터 형식 에 속 하지 않 고 String 은 하나의 대상 입 니 다.대상 의 기본 값 은 null 이기 때문에 String 의 기본 값 도 null 입 니 다.그러나 그것 은 또 하나의 특수 한 대상 으로 다른 대상 에 게 없 는 특성 이 있다.2. new String () 과 new String (") 은 모두 새로운 빈 문자열 을 설명 하 는 것 입 니 다. 빈 문자열 은 null 이 아 닙 니 다. 3. String str =" kville ", String str = new String (" kville ") 의 차이 점 을 볼 때 1: String s0 =" kville ", String s1 =" kville ", String s2 =" kv "+" ill ", System. out. println (s0 = = s1), System. out. println (s0 = = s2)결 과 는 true 입 니 다. 우선, 결 과 는 자바 가 하나의 문자열 상수 만 복사 할 수 있 도록 해 야 합 니 다. 예 를 들 어 s0 과 s1 의 "kville" 는 모두 문자열 상수 이기 때문에 컴 파일 기간 에 확정 되 었 기 때문에 s0 = = s1 은 true 이 고, "kv" 와 "ill" 도 문자열 상수 입 니 다. 한 문자열 이 여러 문자열 상수 로 연결 되 어 있 을 때 문자열 상수 입 니 다.또한, 자신 도 문자열 상수 일 것 입 니 다. 따라서 s2 역시 컴 파일 기간 에 하나의 문자열 상수 로 해석 되 기 때문에 s2 도 상수 탱크 의 "kville" 참조 입 니 다. 따라서 우 리 는 s0 = s1 = = s2 를 얻 을 수 있 습 니 다. new String () 으로 만 든 문자열 은 상수 가 아니 라 컴 파일 기간 에 확정 할 수 없 기 때문에 new String ()만 든 문자열 은 상수 풀 에 넣 지 않 습 니 다. 주소 공간 이 있 습 니 다. 예 를 들 어 2: String s0 = "kville", String s1 = new String ("kville"), String s2 = "kv" + new String ("ill"), System. out. println (s0 = = s1), System. out. println (s0 = s2), System. out. println (s1 = = s2), 결 과 는 false false false 예 2 중 s0 인지 상수 풀 에 있 는 "kville '의 응용 프로그램 입 니 다. s1 은 컴 파일 기간 에 확인 할 수 없 기 때문에 실행 할 때 만 든 새로운 대상' kville '의 참조 입 니 다. s2 는 후반 부 new String (' ill ') 이 있 기 때문에 컴 파일 기간 에 확인 할 수 없 기 때문에 새로 만 든 대상' kville '의 응용 이기 도 합 니 다.그 걸 알 면 왜 이런 결과 가 나 왔 는 지 알 수 있 을 거 야.4. String. intern (): 한 가지 더 소개 합 니 다. class 파일 에 존재 하 는 상수 풀 은 실행 기간 에 JVM 에 의 해 불 러 오고 확장 할 수 있 습 니 다.String 의 intern () 방법 은 상수 탱크 를 확장 하 는 방법 입 니 다.String 인 스 턴 스 str 가 intern () 방법 을 호출 할 때 자바 는 상수 풀 에 같은 유 니 코드 문자열 상수 가 있 는 지 찾 고 있 으 면 인용 을 되 돌려 줍 니 다. 없 으 면 상수 풀 에 유 니 코드 와 같은 문자열 을 추가 하고 인용 을 되 돌려 줍 니 다.예 3 을 보면 알 수 있다. 예 3: String s0 = "kville";String s1=new String("kvill"); String s2=new String("kvill"); System.out.println( s0==s1 ); System.out.println( "**********" ); s1.intern(); s2=s2.intern(); //상수 탱크 의 "kville" 인용 을 s2 System. out. println (s0 = s1) 에 부여 합 니 다.System.out.println( s0==s1.intern() ); System.out.println( s0==s2 ); 결 과 는 false * * * * * * false / / s1. intern () 을 실 행 했 지만 반환 값 은 s1 true / / s1. intern () 에 게 부여 되 지 않 았 습 니 다.방법 은 전역 String 표 에 String 클래스 를 저장 할 수 있 습 니 다. 같은 값 의 유 니 코드 문자열 이 이 표 에 있 으 면 표 에 있 는 문자열 의 주 소 를 되 돌려 줍 니 다. 표 에 같은 값 의 문자열 이 없 으 면 자신의 주 소 를 표 에 등록 합 니 다. "만약 내 가 그 가 말 한 이 전역 의 String 표를 상수 탱크 로 이해한다 면, 그의 마지막 말 은, 표 에 같은 값 의 문자열 이 없다 면, 자신의 주 소 를 표 에 등록 하 는 것 은 잘못된 것 이다. 예 4: String s1 = new String ("kvill") 을 보십시오.String s2=s1.intern(); System.out.println( s1==s1.intern() ); System.out.println( s1+" "+s2 ); System.out.println( s2==s1.intern() ); 결과: false kvill kvill true 는 이 클래스 에서 'kvill' 상수 가 없 었 기 때문에 상수 탱크 에 처음에는 'kvill' 이 없 었 습 니 다. s1. intern () 을 호출 한 후에 상수 탱크 에 'kvill' 상수 가 추가 되 었 습 니 다. 원래 상수 탱크 에 없 었 던 'kvill' 이 존재 합 니 다. '자신의 주 소 를 상수 탱크 에 등록 하 는 것' 이 아 닙 니 다.됐어.s1 = = s1. intern () 은 false 로 원래 의 'kville' 가 존재 한 다 는 것 을 설명 합 니 다.s2 는 현재 상수 탱크 의 "kville" 주소 이기 때문에 s2 = = s1. intern () 은 true 입 니 다.

좋은 웹페이지 즐겨찾기