jdk 1.8 기반 자바 소스 상세 설명 Integer
public final class Integer extends Number implements Comparable<Integer>
Integer 는 final 에 의 해 수식 되 었 기 때문에 이 종 류 는 계승 할 수 없 으 며,동시에 Integer 는 Number 류 를 계승 하 였 기 때문에 Integer 를 int,double,float,long,byte 와 short 형식의 데이터 로 변환 할 수 있 으 며,또한 comparable 인터페이스 도 실현 되 었 기 때문에 Integer 류 도 자 연 스 럽 게 정렬 할 수 있다.구조 방법 은 두 가지 밖 에 없다.
public Integer(int value) {
this.value = value;
}
public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);
}
우 리 는 주로 두 번 째 구조 방법 을 보고 문자열 을 입력 한 다음 에 parseInt 방법 을 호출 한 다음 에 parseInt 의 소스 코드 에 들 어 갑 니 다.
public static int parseInt(String s, int radix)
throws NumberFormatException
{
/*
* WARNING: This method may be invoked early during VM initialization
* before IntegerCache is initialized. Care must be taken to not use
* the valueOf method.
*/
if (s == null) {
throw new NumberFormatException("null");
}
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX");
}
if (radix > Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix +
" greater than Character.MAX_RADIX");
}
int result = 0;
// //
boolean negative = false;
int i = 0, len = s.length();
// ,int -2 31 2 31
int limit = -Integer.MAX_VALUE;
//
int multmin;
//
int digit;
if (len > 0) {
char firstChar = s.charAt(0);
// 0, "-","+"
if (firstChar < '0') { // Possible leading "+" or "-"
//
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+')//
throw NumberFormatException.forInputString(s);
if (len == 1) // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s);
i++;
}
/**
* , result *= radix;
* , 32 int -2147483648~2147483647
*/
multmin = limit / radix;
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
// , radix 10 , :
//Character.digit('a',16), 10;
// , -1:
//Character.digit('t',16), -1,Character.digit('a',10), -1
digit = Character.digit(s.charAt(i++),radix);
// -1
if (digit < 0) {
throw NumberFormatException.forInputString(s);
}
//
if (result < multmin) {
throw NumberFormatException.forInputString(s);
}
/**
*
*/
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;
}
} else {
throw NumberFormatException.forInputString(s);
}
return negative ? result : -result;
}
이 방법 에서 가장 핵심 적 인 절 차 는 1.result*=radix 이다.2、result -= digit; 이 두 단 계 를 거 쳐 문자열 을 수치 형식 으로 변환 합 니 다.대략 절 차 는 이렇다.
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
Integer i5 = Integer.valueOf(100);
Integer i6 = Integer.valueOf(100);
Integer i7 = new Integer(100);
System.out.println("i1 == i2 :" + (i1 == i2));
System.out.println("i3 == i4 :" + (i3 == i4));
System.out.println("i5 == i6 :" + (i5 == i6));
System.out.println("i1 == i5 :" + (i1 == i5));
System.out.println("i1 == i7 :" + (i1 == i7));
}
실행 결 과 는:
i1 == i2 :true
i3 == i4 :false
i5 == i6 :true
i1 == i5 :true
i1 == i7 :false
우 리 는 먼저 첫 번 째 와 두 번 째 결 과 를 살 펴 보 자.똑 같이 두 개의 같은 수 치 를 비교 하 는데 왜 다른 결과 가 있 을 까?이어서 나 는 소스 코드 를 통 해 원인 을 설명 할 것 이다.우선,우 리 는 컴 파일 을 통 해 class 파일 의 바이트 코드 를 가 져 옵 니 다.
그림 에서 볼 수 있 듯 이 Integer i1=100 명령 을 실행 할 때 컴 파일 러 는 Integer 의 정적 방법 인 value Of 를 호출 합 니 다.다음은 value Of 방법 이 어떻게 실현 되 는 지 살 펴 보 겠 습 니 다.
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
이 코드 는 매우 간단 해 보 입 니 다.Integer 에는 정적 내부 클래스 인 Integer Cache 가 있 습 니 다.이 방법 을 호출 할 때 먼저 이 값 이 캐 시 범위 내 에 있 는 지 여 부 를 판단 합 니 다.만약 에 캐 시 에 있 는 수 치 를 직접 되 돌려 주지 않 으 면 새로운 대상 으로 돌아 갑 니 다.여기 서 우 리 는 위의 문제 의 답 을 이미 알 고 있 는 것 같 습 니 다.다음은 정적 내부 류 를 계속 보 세 요.
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
// ( ) (-128)~ 127, java.lang.Integer.IntegerCache.high
//high
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
// 127
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
//
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
//
cache = new Integer[(high - low) + 1];
int j = low;
// -128 ~ 127
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
내부 클래스 는 클래스 가 실례 화 될 때 만 실례 화 되 고 한 번 만 실례 화 된다 는 것 을 알 고 있 습 니 다.캐 시 작업 은 정적 코드 블록 에서 이 루어 집 니 다.즉,클래스 가 실례 화 될 때 데 이 터 는 이미 캐 시 되 었 고 다음 에 사용 할 때 캐 시 된 데 이 터 를 직접 사용 할 수 있 습 니 다.현재 우 리 는 위의 문제 로 돌 아 왔 습 니 다.결과 1 에서 두 데 이 터 는 모두 100 입 니 다.캐 시 범위 에서 i1 과 i2 는 같은 메모리 주 소 를 가리 키 기 때문에 true 로 돌아 갑 니 다.결과 2 중 두 개 수 는 모두 200 으로 캐 시 범 위 를 넘 어 섰 기 때문에 new 에서 두 개의 대상 이 나 왔 기 때문에 그들의 메모리 주소 가 일치 하지 않 고 결 과 를 false 로 되 돌려 주 었 습 니 다.또한,value Of 를 사용 하 는 것 은=연산 자 할당 을 사용 할 때 와 같 기 때문에 결과 3 과 결과 4 는 true 로 되 돌아 갑 니 다.결과 5 에 서 는 new 키 워드 를 직접 사용 하여 대상 을 만 듭 니 다.따라서 메모리 주 소 는 일치 하지 않 을 것 입 니 다.결 과 는 false 입 니 다.
그렇다면 지금 문제 가 또 생 겼 다.그렇다면 나 는 두 정수 의 크기 를 어떻게 판단 할 것 인가?원본 계속 보기
/**
* The value of the {@code Integer}.
*
* @serial
*/
private final int value;
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
public int intValue() {
return value;
}
네,맞아요.두 수치 가 큰 시간 을 비교 할 때 equals 방법 으로 비교 할 수 있 습 니 다.소스 코드 에서 value 의 유형 은 int 형 이 고 intValue 가 돌아 오 는 것 도 value 이기 때문에 두 수의 크기 를 판단 할 수 있 습 니 다.
public static void main(String[] args) {
Integer i1 = 200;
Integer i2 = 200;
System.out.println("i1 == i2 :" + i1.equals(i2)); //true
}
보충:equals 와=의 차이 점:equals 는 두 수치의 크기 를 비교 합 니 다.==두 가지 경우 가 있 습 니 다.기본 데이터 형식 을 비교 하면=equals 와 마찬가지 로 크기 를 비교 합 니 다.참조 형식 이나 배열 이 라면 메모리 주 소 를 비교 합 니 다.
getChars 방법:
static void getChars(int i, int index, char[] buf) {
int q, r;
int charPos = index;
char sign = 0;
if (i < 0) {
sign = '-';
i = -i;
}
// Generate two digits per iteration
//
while (i >= 65536) {
q = i / 100;
// really: r = i - (q * 100);
// ,r
r = i - ((q << 6) + (q << 5) + (q << 2));
i = q;
//
buf [--charPos] = DigitOnes[r];
//
buf [--charPos] = DigitTens[r];
}
// Fall thru to fast mode for smaller numbers
// assert(i <= 65536, i);
//
for (;;) {
// i*(52429/524288)=i*0.10000038146972656=i*0.1=i/10
// 52429 2 19 , , i/10
// , > >
q = (i * 52429) >>> (16+3);
r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
buf [--charPos] = digits [r];
i = q;
if (i == 0) break;
}
if (sign != 0) {
buf [--charPos] = sign;
}
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
jdk1.8 새로운 기능 - Lambda 표현식 및 함수 인터페이스자바 집합에서forEach 방법으로 집합을 옮겨다니면 jdk1이 사용됩니다.8의 새로운 기능: Lambda 표현식과 함수 인터페이스 방법 원본에서 알 수 있듯이forEach 방법은 Iterable 인터페이스(java...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.