Java의 상수 수영장은 일반적으로 두 가지 유형으로 나뉩니다 : 정적 상수 풀과 런타임 상수 풀
정적 상수 풀 : 클래스 파일의 상수 풀. 클래스 파일의 상수 풀에는 문자열 (번호) 리터럴 값, 클래스 및 메소드 정보가 포함되어 있으며 클래스 파일의 대부분의 공간을 차지합니다.
런타임 상수 풀 : JVM이 클래스로드를 완료 한 후 클래스 파일의 상수 풀을 메모리에로드하고 메소드 영역에 저장합니다. 우리가 일반적으로 이야기하는 것은 방법 영역에서 런타임 상수 풀의 상수 풀입니다. 클래스 파일과 비교하여 일정한 풀의 또 다른 중요한 기능은 동적 성입니다. Java 언어는 컴파일 기간 동안 만 상수를 생성 할 필요가 없습니다. 달리기 동안 새로운 상수도 수영장에 배치 될 수 있습니다. 이 기능은 개발자가보다 일반적으로 사용합니다. 문자열 클래스의 인턴 () 메소드.
프로그램 카운터 : 프로그램 실행을위한 파이프 라인이며, 다음에 실행할 명령을 나타냅니다.
로컬 메소드 스택 : JVM이 운영 체제 방법을 호출하는 데 사용하는 스택.
가상 머신 스택 : JVM에서 Java 코드를 실행하는 데 사용되는 스택
가상 머신 힙 : 객체가 저장되는 경우, Java 프로그램에 새로운 모든 객체는 힙에 저장됩니다.
방법 영역 : 상수, 클래스 정보 및 정적 변수는 클래스 파일이 메모리에 저장되는 위치로 이해할 수 있습니다.
일정한 풀링의 이점 :
일정한 풀은 시스템 성능에 영향을 미치는 물체의 빈번한 생성과 파괴를 피하고 물체의 공유를 깨닫는 데 사용됩니다.
예를 들어, 문자열 상수 풀은 컴파일 단계에서 모든 문자열 리터럴을 일정한 풀에 넣는 데 사용됩니다.
1. 메모리 공간 저장 : 상수 풀에 문자 그대로 동일한 문자 그대로의 모든 문자열 상수가 병합되어 하나의 공간 만 가져갑니다.
2. 실행 시간 저장 : 문자열 비교를 수행 할 때 ==는 equals ()보다 빠릅니다. 두 참조 변수의 경우 참조가 동일한지 여부를 결정하기 위해 == 만 사용하므로 실제 값이 동일한 지 여부를 결정할 수 있습니다.
== 기본 데이터 유형과 객체 표현의 의미는 다릅니다.
기본 데이터 유형의 경우 : == 비교는 객체에 대한 기본 데이터 유형의 값입니다. == 비교는 메모리의 객체의 메모리 주소입니다.
8 기본 데이터 유형 포장 클래스 및 상수 풀
Java의 기본 데이터 유형의 대부분의 래퍼 클래스는 일정한 풀링 기술, 즉 바이트, 짧은, 정수, 긴, 캐릭터 및 부울을 구현합니다.
정수 i1 = 40; 정수 i2 = 40; System.out.println (i1 == i2); // true
바이트, 짧은 정수, 긴, 문자,이 5 개의 래퍼 클래스는 기본적으로 해당 유형의 [-128, 127]의 캐시 데이터를 생성하고 상수 풀에 저장합니다. 이 범위를 초과하면 새 객체가 여전히 생성됩니다.
공개 정적 정수 값 (int i) {assert integercache.high> = 127; if (i> = integercache.low && i <= integercache.high) return integercache.cache [i + (-integercache.low)]; 새로운 정수 (I)를 반환합니다. }정수 i1 = 400; 정수 i2 = 400; System.out.println (i1 == i2); // false
2. 두 가지 유형의 부동 소수점 번호 포장 클래스는 플로트 및 더블이 일정한 풀링 기술을 구현하지 않습니다.
이중 D1 = 2.5; 이중 D2 = 2.5; System.out.println (d1 == d2); // false
3. 일정한 풀을 적용하기위한 시나리오
(1) .integeri1 = 40; 정수는 기본 데이터 유형 int의 래퍼 클래스이고 객체이기 때문에 Java는 컴파일 할 때 자동 권투 작업을 수행하고 코드를 Integeri1 = integer.valueof (40)로 직접 캡슐화하여 Constant Pool에서 객체를 사용합니다.
(2) .integeri1 = NewInteger (40); 이 경우 새 객체가 생성됩니다
정수 i1 = 40; 정수 i2 = 새로운 정수 (40); System.out.println (i1 == i2); // false
이 경우 새 정수는 상수 풀에서 기존 상수를 자동 복싱 참조를 수행하지 않지만 힙에 새 객체를 직접 생성합니다.
4. 정수 세부 사항
정수 i1 = 40; 정수 i2 = 40; 정수 i3 = 0; 정수 i4 = 새로운 정수 (40); 정수 i5 = 새로운 정수 (40); 정수 i6 = 새로운 정수 (0); 정수 i7 = 128; 정수 i8 = 128; System.out.println ( "i1 = i2" + (i1 == i2)); System.out.println ( "i1 = i2 + i3" + (i1 == i2 + i3)); System.out.println ( "i1 = i4" + (i1 == i4)); System.out.println ( "i4 = i5" + (i4 == i5)); System.out.println ( "i4 = i5 + i6" + (i4 == i5 + i6)); System.out.println ( "40 = i5 + i6" + (40 == i5 + i6)); System.out.println ( "i7 = i8" + (i7 == i8));
i1 = i2 truei1 = i2+i3 truei1 = i4 falsei4 = i5 falsei4 = i5+i6 true40 = i5+i6 truei7 = i8 false
설명 : + 연산자가 정수 객체에 적용되지 않기 때문에 명령문 i4 == i5 + i6. 먼저, i5와 i6은 자동 Unboxing 작업을 수행하고 값, 즉 i4 == 40을 추가합니다. 그런 다음 정수 객체를 숫자 값과 직접 비교할 수 없으므로 I4는 자동으로 Unbox를 자동으로 Unbox를 변환하여 int 값 40으로 변환합니다. 마지막으로,이 문장은 수치 비교를 위해 40 == 40으로 변환됩니다.
문자열 클래스 및 상수 풀
1. 문자열 객체를 만드는 방법
문자열 s1 = "abdcd"; String s2 = new String ( "abcd"); system.out.println (s1 == s2); // false
이 두 가지 다른 방식의 창조 방법에는 차이가 있습니다. 첫 번째는 상수 수영장에서 물체를 가져 오는 것이고, 두 번째는 힙 메모리 공간에서 새 객체를 만드는 것입니다.
새 개체를 사용하면 힙에 생성됩니다.
2. 연결 표현+
(1). "+"연결에 의해 생성 된 새 개체 만 "" "텍스트를 포함하여 생성 된 문자열 객체간에 문자열 상수 풀에 추가됩니다.
(2). "+"를 통해 직접 연결된 두 객체 참조 또는 새 모드를 통해 생성 된 객체와 같은 다른 양식의 경우, 결과 새 개체는 문자열 상수 풀에 추가되지 않습니다.
문자열 str1 = "str"; String str2 = "ing"; 문자열 str3 = "str" + "ing"; String str4 = str1 + str2; system.out.println (str3 == str4); // false String str5 = "string"; System.out.println (str3 == str5); // true
공개 정적 최종 문자열 a = "ab"; // 상수 apublic 정적 최종 문자열 b = "cd"; // 상수 bpublic static void main (String [] args) {String s = a + b; // + 연결 문자열 t = "abcd"로 s를 초기화합니다. if (s == t) {system.out.println ( "s와 동일합니다. 동일한 객체"); } else {system.out.println ( "s는 동일하지 않으며 동일한 객체가 아니다"); }} s는 t와 같고, 동일한 객체입니다.A와 B는 상수이며 값은 고정되어 있으므로 S 값도 고정되어 클래스가 컴파일 될 때 결정됩니다. 다시 말해 : 문자열 s = a+b; 에 해당 : 문자열 s =”ab”+”cd”;
공개 정적 최종 문자열 a; // 상수 apublic 정적 최종 문자열 b; // constant bstatic {a = "ab"; B = "CD"; } public static void main (string [] args) {// + concatenation string을 사용하여 s = a + b; 문자열 t = "abcd"; if (s == t) {system.out.println ( "s와 동일합니다. 동일한 객체"); } else {system.out.println ( "s는 동일하지 않으며 동일한 개체가 아니다"); }} s는 t와 같지 않으며 동일한 개체가 아닙니다.A와 B는 상수로 정의되지만 그 중 어느 것도 즉시 할당되지 않습니다. S의 값을 계산하기 전에 할당 된 시점 및 할당 된 값은 변수입니다. 따라서 A와 B가 할당되기 전에 해당 속성은 변수와 유사합니다. 컴파일 기간 동안 S를 결정할 수는 없지만 런타임에서만 생성 할 수 있습니다.
3.Strings1 = Newstring ( "XYZ"); 얼마나 많은 객체가 생성 되었습니까?
클래스 로딩 단계와 실제 실행을 고려하십시오.
(1) 클래스 로딩은 클래스에서 한 번만 수행됩니다. 클래스가로드되면 "XYZ"가 생성되고 상주됩니다 (클래스가로드되기 전에 "XYZ"문자열이 상주 된 경우, 상주 할 "XYZ"인스턴스를 반복적으로 생성 할 필요가 없습니다). 상주 된 문자열은 전 세계적으로 공유 된 문자열 상수 풀에 배치됩니다.
(2)이 코드가 실행되면 "XYZ"리터럴에 해당하는 문자열 인스턴스가 고정되어 반복적으로 생성되지 않습니다. 따라서이 코드는 상수 풀에있는 물체의 사본을 복사하여 힙에 넣고 힙의 객체에 대한 참조를 S1로 건네줍니다.
이 진술은 2 개의 객체를 만듭니다.
4.java.lang.string.intern ()
클래스 파일 상수 풀과 비교하여 런타임 상수 풀의 또 다른 중요한 기능은 동적입니다. Java 언어는 컴파일 기간 동안 만 상수를 생성 할 필요가 없습니다. 즉, 클래스 파일의 상수 풀의 내용은 메소드 영역에 들어갈 수 있습니다. 런타임 동안 새로운 상수가 풀에 배치 될 수 있습니다. 이 기능은 개발자가보다 일반적으로 사용합니다. 문자열 클래스의 인턴 () 메소드.
String의 Intern () 메소드는 상수 풀에 동일한 문자열이 있는지 여부를 알게됩니다. 있으면 문자열에 대한 참조를 반환합니다. 없으면 자체 문자열이 상수 풀에 추가됩니다.
public static void main (String [] args) {String s1 = new String ( "Computer"); 문자열 s2 = s1.intern (); 문자열 s3 = "컴퓨터"; System.out.println ( "S1 == S2?" + (S1 == S2)); System.out.println ( "S3 == S2?" + (S3 == S2);}S1 == S2? falses3 == S2? 진실
요약
위의 것은 Java Constant Pools를 깊이 탐색하는 것입니다. 모든 사람에게 도움이되기를 바랍니다. 관심있는 친구는이 사이트의 다른 관련 주제를 계속 참조 할 수 있습니다. 단점이 있으면 메시지를 남겨 두십시오.