왜 자바 에 값 만 전달 되 는 지

5960 단어 자바값 전달
매개 변수 전달
우리 가 일상적으로 코드 를 작성 하 는 과정 에서 호출 함 수 는 아마도 가장 흔히 볼 수 있 는 조작 일 것 이다.그렇다면 함 수 를 호출 할 때 인 자 는 어떻게 전달 되 나 요?
값 전달
많은 사람들 이 C 언어 를 배우 고 입문 할 것 이 라 고 믿 습 니 다.처음에 코드 를 쓸 때 가장 많이 사용 하 는 것 은 바로 값 전달 입 니 다.

void plus_one(int a){
  a++;
  printf("a: %d", a);
}

int main(){
  int n = 10;
  plus_one(n);
  printf("n:%d", n);
  return 0;
}
이것 은 간단 한 값 전달 의 예 입 니 다.더 말 할 필요 가 없습니다.plus원 함수 의 역할 은 들 어 오 는 수 를 하나 더 해서 출력 하 는 것 이다.이른바 값 전달 이란 실 삼 n 의 값 을 형 삼 a 에 직접 부여 하 는 것 이다.값 이 완 성 된 후에 둘 은 더 이상 관련 이 없다.
따라서 위의 코드 는 다음 과 같다.

int main(){
  int n = 10;
  
  // plus_one start
  int a;
  a = n;
  a++;
  printf("a: %d", a);
  // plus_one end
  
  printf("n:%d", n);
  return 0;
}
이 를 통 해 알 수 있 듯 이 값 전달 은 간단 하고 직관 적 이지 만 호출 함 수 는 실제 인삼 n 의 값 을 바 꿀 수 없습니다.
포인터 전달
그러면 우리 가 실제 인삼 의 가 치 를 바 꿔 야 할 때 우 리 는 지침 으로 전달 하 는 것,즉 주소 전달 이 라 고 생각 할 것 이다.

void plus_one(int* p){
  *p = *p + 1;
}

int main(){
  int n = 10;
  plus_one(&n);
  printf("The result is %d", n);
  return 0;
}
여기,우 리 는 실제 인삼 의 주 소 를 plus 에 전송 합 니 다.원 함수,함수 에서 포인터 p 가 가리 키 는 값,즉 n 을 직접 조작 하면 자 연 스 럽 게 실제 인삼 n 의 값 을 바 꿀 수 있 습 니 다.
실제로 지침 전달 도 값 전달 이다.우 리 는 위의 코드 를 고 쳐 썼 다.

int main(){
  int n = 10;
  
  // plus_one start
  int* p;
  p = &n;
  *p = *p + 1;
  printf("The result is %d", n);
  // plus_one end
  
  return 0;
}
이 를 통 해 알 수 있 듯 이 포인터 전달 이란 변수 n 의 주소 값 을 포인터 변수 p 에 부여 하 는 것 일 뿐 실제 적 으로 값 전달 이기 도 합 니 다.
따라서 C 언어 에서 값 만 전달 된다 는 것 을 무책임 하 게 요약 할 수 있다.
인용 전달
지침 도 강하 지만 코드 가 읽 기 쉽 지 않 아 이해 하기 어렵 다 는 지적 도 많다.C++는 C 언어의 초대형 컵 으로 인용 전달 을 도입 하여 지침 전달 을 간소화 하 는 표기 법 을 도입 했다.

void plus_one(int& a){
  a++;
}

int main(){
  int n;
  plus_one(n);
  printf("The result is %d", n);
  return 0;
}
C++에서&연산 자 를 다시 불 러 와 인용 전달 을 실현 했다.구체 적 으로 plus 호출원 함수 일 때 함수 호출 창고 에 변수 n 의 주 소 를 저장 합 니 다.n 의 값 이 아 닙 니 다.그래서 plus원 의 변수 a 는 n 의'별명'에 해당 하 며,a 를 조작 할 때 n 의 값 이 자 연 스 럽 게 변 합 니 다.
이 를 통 해 알 수 있 듯 이 전 달 된 바 텀 도 할당 작업 이다.
자바 의 매개 변수 전달
그렇다면 자바 에 서 는 전달 을 인용 하 는 것 일 까,값 전달 일 까?
자바 에서 변 수 는 기본 변수 와 대상 으로 나 뉘 는데,우 리 는 각각 토론 해도 무방 하 다.
기본 변수 유형
우선,int,char 등 기본 유형 에 대해 자바 는 값 을 사용 하여 전달 되 므 로 검증 하기 쉽다.

static void plusOne(int a){
  a++;
  System.out.println("a: " + a);
}

public static void main(String[] args){
  int n = 10;
  plusOne(n);
	System.out.println("n: " + n);
}
분명히 C 언어 와 마찬가지 로 여기 n 의 값 은 변 하지 않 을 것 이다.
대상

public class PassObject {
  public static void main(String[] args) {
    Dog myDog = new Dog("Test");
    foo(myDog);
    System.out.println(myDog.getName());// TestPlus
  }

  public static void foo(Dog dog) {
    dog.setName("TestPlus");
  }
}

class Dog{

  private String name;

  public Dog(String name) {
    this.name = name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }
}
위의 예 를 통 해 알 수 있 듯 이 대상 의 인용 을 전달 할 때 대상 의 속성 변 수 를 바 꿀 수 있 습 니 다.그럼 자바 가 전달 대상 을 매개 변수 로 할 때 인용 전달 인가요?
실제로 그렇지 않다.자바 에 서 는 대상 의 인용 이 사실상 대상 의 지침 에 해당 한다.자바 에서 대상 을 조작 하 는 것 은 인용 조작 이라는 경 로 를 통 해서 만 가능 합 니 다.어떤 의미 에서 자바 에 서 는 대상 을 직접 조작 할 수 없다.
즉,상례 에서 참 조 를 전 달 했 을 때 myDog 대상 의 실례 에 대해 어떠한 조작 도 하지 않 고 myDog 인용 값 을 foo 함수 의 로 컬 변수 dog 에 부 여 했 을 뿐이다.인용 전달 처럼 대상 실 체 를 전송 하 지 는 않 았 으 나 스 택 에 만 대상 참조 작업 을 저장 합 니 다.그래서 자바 에서 대상 을 전달 할 때 도 값 전달 입 니 다.
그래서 자바 에 서 는 값 만 전달 합 니 다.
언급 할 만하 다
그러나 이런 결론 이 의 심 스 러 울 수 있 는 특수 한 상황 도 있다.
배열
위 에 서 는 기본 변수 유형 과 대상 만 분 석 했 습 니 다.배열 은 요?
실제로 자바 의 배열 도 하나의 대상 이 고 배열 류 도 Object 류 에서 계승 된다.배열 을 매개 변수 로 할 때 도 전달 하 는 배열 의 인용 이 고 배열 의 실 체 를 전달 하지 않 았 습 니 다.

public static void changeContent(int[] arr) {
  arr[0] = 10;
}

public static void changeRef(int[] arr) {
  arr = new int[2];
  arr[0] = 15;
}

public static void main(String[] args) {
  int [] arr = new int[2];
  arr[0] = 4;
  arr[1] = 5;

  changeContent(arr);
  System.out.println(arr[0]); // 10
  changeRef(arr);
  System.out.println(arr[0]); // 10
}
상례 에서 볼 수 있 듯 이 들 어 오 는 그룹 인용 을 새로운 그룹 에 부여 하면 이 인용 은 이전의 그룹 을 조작 할 수 없다.
인용 에 대해 영 어 는 reference 입 니 다.사실은 저 는 스스로 문장 손잡이 로 번역 하 는 것 이 더욱 적절 하 다 고 생각 합 니 다.인용 은 하나의 손잡이,하나의 Handler 와 같 습 니 다.당신 은 그것 으로 실 체 를 조작 할 수 있 지만 그 는 실체 자체 가 아 닙 니 다.손잡이 가 게임 기 를 조종 할 수 있 지만 게임 기 자체 가 아니다.이 손 잡 이 를 다른 게임 기 에 연결 할 때 이전의 게임 기 를 조종 할 수 없다.
패키지 클래스 와 String

public static void main(String[] args) {
  Integer n = 1;
  plusOne(n);
  System.out.println(n); // 1
}

private static void plusOne(Integer n) {
  n = n + 1;
  System.out.println(n);// 2
}
이 코드 에서 n 은 Integer 형식의 인 스 턴 스 핸들 이지 만 대상 의 값 을 바 꾸 는 데 성공 하지 못 했 습 니 다.왜 일 까요?
Integer 클래스 에서 대응 하 는 값 을 저장 하 는 속성 은 value 입 니 다.설명 은 다음 과 같 습 니 다.

private final int value;
이 를 통 해 알 수 있 듯 이 value 값 은 고 칠 수 없습니다.그 추가 작업 은 어떻게 이 루어 집 니까?
상기 하 나 를 추가 하 는 과정 에서 새로운 Integer 대상 을 다시 만 들 고 이 대상 을 인용 n 에 부여 합 니 다.이렇게 되면 이전의 대상 은 자연히 변 하지 않 을 것 이다.
실제로 포장 류 와 String 류 의 값 은 모두 final 이기 때문에 실행+를 수행 하 는 과정 에서 대상 을 다시 만 든 다음 에 값 을 부여 합 니 다.
이상 은 자바 에서 값 만 전달 하 는 상세 한 내용 입 니 다.자바 값 전달 에 관 한 자 료 는 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기