두 개의 int형 데이터를 교환하는 정적 방법

3674 단어 Integerint

전에 친구가 면접에서 아주 재미있는 문제를 만났는데 제목은 다음과 같다.
 
    public static void main(String[] args) throws Exception{
        int a = 1;
        int b = 2;
        swap(a, b);
        System.out.println("a is "+a+", b is "+b);
    }

 
swap 방법을 작성하여 a, b 두 값을 데이터로 교환합니다. 즉, a=2, b=1
이것은 개인 지식 범위 내에서 실현될 수 없다고 생각하고 비교적 좋은 해석을 찾았다. 다음과 같다.
자바의 기본 데이터 형식은 모두 8가지입니다. 즉, int,short,long,byte,float,double,boolean,char(주의, String의 기본 형식은 없습니다).
이런 유형의 정의는 int a=1과 같다.long b = 255L;의 형식으로 정의되었습니다.
예를 들어 int a = 1;이곳의 a는 int 형식을 가리키는 인용으로 1이라는 글자 값을 가리킨다.이 글자 값의 데이터는
크기가 알 수 있기 때문에 생존 기간은 알 수 있다(이 글자 값은 특정한 프로그램 블록에 정의되어 있고 프로그램 블록이 종료되면 필드 값은 사라진다). 속도를 추구하는 이유로 창고에 존재한다.
 
또한 창고는 매우 중요한 특수성을 가지고 있는데 창고에 존재하는 데이터가 공유될 수 있다는 것이다.예:
우리는 동시에 다음과 같이 정의합니다.
 
   int a=1;
   int b=2;
 
컴파일러가 inta=1을 먼저 처리합니다.
우선 창고에 변수가 a인 인용을 만들고 액면가가 1인 주소를 찾습니다. 찾지 못하면 1이라는 액면가를 저장하는 주소를 열고 a를 3인 주소로 가리킵니다.
이어서 intb=2를 처리한다.b 인용 변수를 만든 후, 창고에 2라는 글자 값이 있기 때문에, b를 2의 주소로 직접 가리킵니다.이렇게 해서 a와 b가 동시에 2를 가리키는 상황이 나타났다.
 
a와 b의 값을 정의한 후 a=4;
그러면 b는 4와 같지 않거나 2와 같지 않다.컴파일러 내부에서 만났을 때, 창고에 4의 글자 값이 있는지 다시 검색하고, 없으면 주소를 다시 열어 4의 값을 저장합니다.
만약 이미 있다면, 직접 a를 이 주소로 가리킨다.따라서 a값의 변화는 b값에 영향을 주지 않는다.
그럼 이걸 어떻게 해결하지?
코드 붙이기:
   
public static void main(String[] args) throws Exception {
        Integer a = 1333;
        Integer b = 2333;
        swap(a, b);
        System.out.println("a is "+a+", b is "+b);
    }
    private static void swap(Integer x, Integer y) throws Exception {
        int z= x;
        Field field = Integer.class.getDeclaredField("value");
        field.setAccessible(true);
        field.set(x, y);
        field.set(y, z);
        System.out.println("x is "+x+", y is "+y);
    }

 
기본 유형을 대상 유형으로 바꾸면 되지 않을까요?보아하니 아무런 문제가 없을 것 같고, 출력 결과도 정확한데, a=1, b=2를 시험해 보세요!
결과는 22가 되었는데 이상하지 않습니까? JD가 역번역한 후에 다음과 같습니다.
 
    private static void swap(Integer x, Integer y) throws Exception {
        int z= x;
        Field field = Integer.class.getDeclaredField("value");
        field.setAccessible(true);
        field.set(x, y);
        field.set(y, Integer.valueOf(z));
        System.out.println("x is "+x+", y is "+y);
    }

 
    
Integer 소스 valueOf(i) 방법을 보면 그 이유를 알 수 있습니다!
 
  public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

 
Integer는 자체 버퍼[-128-128],field가 있습니다.set(x, y);이 행 코드는 버퍼 안의 값을 수정하고 IntegerCache를 수정합니다.cache[129]=IntegerCache.cache[130]=2
그래서 a=b=2를 어떻게 깨요?
IntegerCache에서 가져온 z 값을 제거하지 않으면 new로 바로 이동합니다.코드 수정
    field.set(y, z);필드로 바꾸다.set(y, new String(z));문제를 해결하려면 공통 IntegerCache를 사용하지 않고 코드를 계속 수정하는 것이 좋습니다.
    
    public static void main(String[] args) throws Exception {
        Integer a = new Integer(1);
        Integer b = new Integer(2);
        swap(a, b);
        System.out.println("a is "+a+", b is "+b);
    }

 
성공했어.
요약:
1) int 데이터는 상량 풀에 저장되고 주소는 창고에 있습니다.
2) Integer가 정의한 두 변수(예: integer a=1;integer b=2)는 하나의 IntegerCache를 사용합니다.

좋은 웹페이지 즐겨찾기