>  기사  >  Java  >  Java의 상수 풀이란 무엇입니까? Java 상수 풀 소개

Java의 상수 풀이란 무엇입니까? Java 상수 풀 소개

不言
不言원래의
2018-09-20 14:40:448346검색

이 기사에서는 Java의 상수 풀이 무엇인지 설명합니다. Java 상수 풀의 도입에는 특정 참고 가치가 있습니다. 도움이 필요한 친구가 참고할 수 있기를 바랍니다.

Java의 상수 풀

Java 가상 머신 jvm에서 메모리 분배는 가상 머신 힙, 프로그램 카운터, 로컬 메소드 스택, 가상 머신 스택, 메소드 영역입니다.

Java의 상수 풀이란 무엇입니까? Java 상수 풀 소개

프로그램 카운터는 jvm 실행 프로그램의 파이프라인이며 일부 명령을 저장하는 데 사용됩니다. 로컬 메서드 스택은 jvm 운영 체제 메서드에서 사용하는 스택이고, 가상 머신 스택은 프로그램 코드를 실행하는 데 사용되는 스택입니다. 메소드 내에는 클래스 변수, 클래스 정보, 메소드 정보, 상수 풀(테이블 형태로 존재하는 심볼 참조)이 포함됩니다. 힙은 가상 머신이 프로그램 코드를 실행하는 데 사용하는 힙입니다.

꾸준하게? 한번 값을 부여하면 변경할 수 없는 수량입니다. final로 수정된 멤버변수는 상수입니다.

클래스 파일 상수 풀이란 무엇인가요?

클래스 파일에는 클래스 버전 정보, 필드 정보, 메소드, 인터페이스 및 기타 정보가 있고 상수 풀도 있다는 것을 알고 있습니다. 이것이 클래스 파일 상수 풀입니다.

클래스 파일 상수 풀은 주로 저장에 사용되나요?

컴파일로 생성된 다양한 리터럴과 기호 참조를 저장합니다. 컴퓨터 과학에서 리터럴은 소스 코드에서 고정된 값을 표현하는 데 사용되는 표현입니다. 기호 참조는 참조된 대상을 설명하는 데 사용되는 기호 집합입니다. 명확하게 사용할 수 있는 한 모든 형태의 리터럴이 될 수 있습니다. 목표물을 찾아보세요.

상수 풀은 테이블 형식으로 존재합니다(테이블은 기호 참조가 아닌 문자열 값을 저장하는 데 사용됨). 실제로 두 가지 유형으로 나눌 수 있습니다. 하나는 정적 상수 풀이고 다른 하나는 런타임 상수 풀입니다. 11의 상수 테이블에는 상수 풀의 각 상수가 테이블을 나타냅니다.

상수 테이블

유형의 리터럴 값
상수 테이블 유형 플래그 값 Description
CONSTANT_Utf8 1 UTF-8로 인코딩된 유니코드 문자열
CONSTANT_Integer 3 int 리터럴 값
CONSTANT_Float 4 float
CONSTANT_Long 5 long
CONSTANT_Double6 이중 유형의 리터럴 값
CONSTANT_Class 7 클래스 또는 인터페이스에 대한 기호 참조
CONSTANT_String 8 문자열 유형의 리터럴 값에 대한 참조
CONSTANT_Fieldref 9 필드 기호
CONSTANT_Methodref 10 클래스의 메서드에 대한 기호 참조
CONSTANT_InterfaceMethodref 11 인터페이스의 메서드에 대한 기호 참조
CONSTANT _Name AndType 12 을(를) 메소드의 필드 또는 부분 기호 참조

상수 풀

Integer integer1 = 127;
Integer integer2 = 127;
System.out.println(integer1 == integer2);
// true
Integer integer1 = 128;
Integer integer2 = 128;
System.out.println(integer1 == integer2);
// false

Java에서 "==" 기호는 주소를 비교하는 데 사용됩니다. "equals" 기호는 기본적으로 주소를 비교하는 데 사용되는 "=="와 동일한 기호입니다.

String string1 = "dashu";
String string2 = "dashu";
System.out.println(string1==string2);
// true
String string1 = "dashu";
String string3 = new String("dashu");
System.out.println(string1 == string3);
// false

String str = new String("dashu"); 얼마나 많은 객체가 생성되나요?
답은 2 또는 1입니다.

new String("dashu");에서 "dashu" 리터럴 값이 이미 상수 풀에 나타나면 하나의 객체만 생성되고, 그렇지 않으면 두 개의 객체가 생성됩니다.

원리: 리터럴 "dashu"가 나타나면 시스템은 문자열 상수 풀에서 검색하여 동일한 문자열이 존재하는지 확인합니다. 그렇다면 새 객체를 생성하지 않고, 그렇지 않으면 리터럴 값 "dashu"를 사용합니다. ", String 개체를 만듭니다. 그리고 new 키워드를 사용하는 new String("dashu")은 확실히 새 개체를 만든 다음 초기화를 위해 String 매개 변수를 받는 생성자를 호출한다는 의미입니다.

string1 == string3.intern()으로 변경하면 상수 풀에 있는 리터럴 값의 주소가 반환되기 때문에 결과는 true가 됩니다.

스택: 스레드 스택 및 네이티브 메서드 스택

// 源码
public class Object{
 private static native void registerNatives();
 static{
  registerNatives();
 }
}
// 源码
public boolean equals(Object obj){
 return (this == obj);
}
// 源码
public String toString(){
 return getClass().getName() + "@" + Integer.toHexString(hasCode());
}
// 源码
protected native Object clone() throws CloneNotSupportedException;

native 수정자로 수정된 것은 c 언어를 호출하거나 <code>JNI를 통해 호출하는 것입니다. > 코드>C++가 실행되었습니다. native修饰符修饰的是通过<code>JNI来调用c语言或是c++执行的。

所有的类都是Object的子类。

万物皆对象
// 源码注解
Class {@code Object} is the root of the  class hierarchy.
Every class has {@code Object} as a superclass.
All objects, including arrays, implements the methods of this class.
@ see java.lang Class
@ since JDK1.0

常量池:
Class文件中存储所有常量
在Java中说过常量池可以分两种形态,静态常量池和运行时常量池。

静态常量池就是class文件中的常量池有字符串字面量,类信息,方法的信息等,占用了class文件较大部分的空间,在常量池中主要存放的是字面量和符号引用量。

运行时常量池是java虚拟机在完成类加载后的操作,将class文件中的常量池加载到内存中,并保证在方法区,我们口中的常量池是在方法区中运行的常量池,运行时常量池具有动态性,在运行期间也能产生新的常量放入池中,就是上方写过的代码。常量不一定要在编译期间产生,也可以在运行期间产生新的产量放入到池中。

如下解析:

Java虚拟机jvm在执行某个类的时候,要经过类从加载到内存中,到卸载为止。

整个过程为 加载,验证,准备,解析,初始化,使用,卸载。

加载,

验证,class文件的版本是否能兼容当前的Java虚拟机版本,然后class文件要满足虚拟机的规范。

准备,需要准备什么呢?
就是要进行类成员的初始化为初始值,其中为final修饰的类变量除外,final变量就直接初始化为变量值,而类成员不一样。

解析,什么是解析呢?
就是把符号引用解析为直接引用,就是我们变量xxx,这种代表变为直接引用,什么是直接引用呢?就是内存地址,如我们常见的xxx0203r0e,这种。

初始化,把关于static修饰的变量或者是static静态代码块按照顺序组成构造器进行初始化变量。

使用,

卸载

当类加载到内存后,jvm会将class常量池中的内容存放到运行时常量池中,所以运行时常量池每个类都有一个的。

class常量池是存放字面量和符号的引用,是对象的符号引用值,经过解析就是把符号引用解析为直接引用,在编译阶段存放的是常量的符号引用,进行解析后就是直接引用了。然后在全局常量池中保证每个jvm只有一份,存放的是字符串常量的直接引用值。

如果改为`string1 == string3.intern()`结果为true,因为返回的是常量池里面字面值的地址。

String类的intern()方法,会在常量池中查找是否有一份equal()相等的字符串。

String string1 = "dashu";
String string3 =  new String("dashu");
System.out.println(string1==string3.intern());

如果常量池中没有这个“dashu”字面量,那么就先把这个字面量“dashu”

모든 클래스는 Object의 하위 클래스입니다.

rrreee

상수 풀:

모든 상수는 클래스 파일에 저장됩니다.

자바에서는 상수 풀을 정적 상수 풀과 런타임 상수 풀 두 가지 형태로 나눌 수 있다고 합니다. 🎜🎜정적 상수 풀은 클래스 파일의 상수 풀로 문자열 리터럴, 클래스 정보, 메소드 정보 등이 포함되어 있습니다. 클래스 파일 공간의 많은 부분을 차지합니다. 상수 풀은 주로 리터럴 및 기호 참조를 저장합니다. . 🎜🎜런타임 상수 풀은 클래스 로딩이 완료된 후 Java 가상 머신의 작업으로, 클래스 파일에 있는 상수 풀을 메모리에 로드하고 우리가 참조하는 상수 풀이 무엇인지 확인합니다. 메서드 영역에서 실행되는 상수 풀, 런타임 상수 풀은 동적이며 런타임 중에 새로운 상수를 생성하여 풀에 넣을 수 있습니다. 이는 위에 작성된 코드입니다. 컴파일 중에 상수를 생성할 필요가 없으며 런타임 중에 새 출력을 생성하여 풀에 넣을 수도 있습니다. 🎜🎜다음 분석: 🎜🎜Java 가상 머신 jvm이 특정 클래스를 실행할 때 메모리 로드부터 언로드까지 클래스를 거쳐야 합니다. 🎜🎜전체 프로세스는 로딩, 검증, 준비, 구문 분석, 초기화, 사용 및 제거입니다. 🎜🎜Load, 🎜🎜클래스 파일의 버전이 현재 자바 가상 머신 버전과 호환되는지 확인하고, 클래스 파일이 가상 머신의 사양을 만족해야 합니다. 🎜🎜준비, 무엇을 준비해야 할까요? 🎜final에 의해 수정된 클래스 변수를 제외하고는 클래스 멤버를 초기 값으로 초기화해야 합니다. 최종 변수는 변수 값으로 직접 초기화되지만 클래스 멤버는 다릅니다. 🎜🎜분석, 분석이란? 🎜기호 참조를 변수 xxx인 직접 참조로 구문 분석하는 것입니다. 이 표현은 직접 참조가 무엇인가요? 이는 일반적인 xxx0203r0e와 같은 메모리 주소입니다. 🎜🎜초기화, 수정된 정적 변수 또는 정적 정적 코드 블록을 사용하여 변수를 초기화하기 위한 생성자를 형성합니다. 🎜🎜Use, 🎜🎜Uninstall🎜🎜클래스가 메모리에 로드되면 jvm은 클래스 상수 풀의 내용을 런타임 상수 풀에 저장하므로 각 클래스에는 하나의 런타임 상수 풀이 있습니다. 🎜🎜클래스 상수 풀은 리터럴 및 기호에 대한 참조를 저장합니다. 구문 분석 후 기호 참조는 컴파일 단계에서 상수의 기호 참조로 저장됩니다. 파싱 ​​후에는 직접 참조됩니다. 그런 다음 각 jvm에 문자열 상수의 직접 참조 값을 저장하는 전역 상수 풀에 복사본이 하나만 있는지 확인하십시오. 🎜`string1 == string3.intern()`으로 변경하면 상수 풀에 있는 리터럴 값의 주소가 반환되므로 결과는 true가 됩니다. 🎜🎜String 클래스의 intern() 메서드는 상수 풀을 검색하여 equal()과 동일한 문자열이 있는지 확인합니다. 🎜rrreee🎜상수 풀에 "dashu" 리터럴이 없으면 먼저 "dashu" 리터럴 값을 상수 테이블에 넣은 다음 주소를 반환합니다. 상수 테이블. 🎜🎜상수 풀의 장점🎜🎜상수 풀은 빈번한 객체 생성과 소멸로 인한 시스템 성능 저하를 피할 수 있으며, 객체 공유를 실현하여 메모리 공간과 실행 시간을 절약할 수 있습니다. 🎜

위 내용은 Java의 상수 풀이란 무엇입니까? Java 상수 풀 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.