>  기사  >  Java  >  값이 Java에서만 전달되는 이유는 무엇입니까?

값이 Java에서만 전달되는 이유는 무엇입니까?

王林
王林앞으로
2023-04-18 11:28:02886검색

고전적인 질문

Java에서 전달되는 매개변수는 값으로 전달되나요, 아니면 참조로 전달되나요? 이 질문은 매우 기본적이지만 많은 사람들이 약간 혼란스러워합니다.

형식 매개변수와 실제 매개변수

먼저 매개변수에 대한 몇 가지 개념을 이해해야 합니다.

형식 매개변수: 들어오는 함수를 수신하기 위해 함수를 정의할 때 사용되는 매개변수, 예를 들어, 함수를 작성하면 함수의 매개변수는 형식 매개변수입니다.

public void test(String str) { //str为形式参数     
    System.out.println(str); 
}

실제 매개변수: 함수를 호출할 때 함수 이름 뒤 괄호 안의 매개변수는 실제 매개변수라고 하며 특정 값을 가져야 합니다. 다음 예에서 볼 수 있듯이

public static void main(String[] args) {     
    A a = new A();     
    a.test("小 明"); //"小 明"则为实际参数 
}

에서 볼 수 있듯이 매개변수화된 함수를 호출하면 실제 매개변수가 형식 매개변수로 전달되는 것을 확인할 수 있습니다.

이 전달 프로세스에는 일반적으로 매개변수에 대한 두 가지 상황이 있습니다.값 전달과 참조 전달.

  • 값 전달: 함수를 호출할 때 실제 매개변수를 복사하여 함수에 전달합니다. 함수 내부의 매개변수를 수정하면 실제 매개변수에 영향을 주지 않습니다. 기본 개체

  • 참조로 전달: 메서드는 실제 매개변수가 참조하는 주소를 수신하고 복사본을 생성하지 않습니다. 형식 매개변수를 수정하면 실제 매개변수에 영향을 미칩니다. 즉,
  • 가 복사본을 생성하지 않는 경우 이는 기본 객체에 영향을 미칩니다

  • 또한 알아야 할 사항: Java에는 2가지 데이터 유형이 있으며, 주요 데이터 유형은
기본 데이터 유형

참조 데이터 유형입니다. 단, 8가지 기본 데이터 유형은 제외됩니다. , 이들은 모두 참조 데이터 유형, 즉 byte, short, int, long, char, boolean, float, double입니다.Java는 값으로 전달되나요, 아니면 참조로 전달되나요?byte,short,int,long,char,boolean,float,double

Java是值传递还是引用传递

对于这个问题,我们先来看几个例子慢慢道来:

传参的类型:基本数据类型

public class TestBasic {
    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 20;
        change(num1, num2);
        System.out.println("==============");
        System.out.println("num1 = " + num1);
        System.out.println("num2 = " + num2);
    }

    public static void change(int param1, int param2) {
        System.out.println("param1 = " + param1);
        System.out.println("param2 = " + param2);
        param1 = 333;
        param2 = 444;
        System.out.println("after change....");
        System.out.println("param1 = " + param1);
        System.out.println("param2 = " + param2);
    }
}

结果:

param1 = 10
param2 = 20
after change....
param1 = 333

param2 = 444

==============

num1 = 10
num2 = 20

我们可以发现,change()方法内对变量重新赋值,并未改变变量num1和num2的值,改变的只是change()方法内的num1和num2的副本。我们需要知道,基本数据类型在内存中只有一块存储空间,分配在栈stack中。

Java传参的类型如果是基本数据类型,是值传递

값이 Java에서만 전달되는 이유는 무엇입니까?

传参的类型:引用数据类型

public class TestQuote {

    public static void main(String[] args) {
        String str = "小明";
        StringBuilder str2 = new StringBuilder("今天天气好");
        change(str,str2);
        System.out.println("==============");
        System.out.println("str = " + str);
        System.out.println("str2 = " + str2);

    }

    public static void change(String param1,StringBuilder param2) {
        System.out.println("param1 = " + param1);
        System.out.println("param2 = " + param2);
        param1= "小张";
        param2.append(",我们去钓鱼");
        System.out.println("after change....");
        System.out.println("param1 = " + param1);
        System.out.println("param2 = " + param2);
    }
}

结果:

param1 = 小明
param2 = 今天天气好
after change....
param1 = 小张

param2 = 今天天气好,我们去钓鱼

str = 小明
str2 = 今天天气好,我们去钓鱼

我们发现str变量没有改变,但是str2变量却改变了,大家是不是迷惑了:Java传参的类型如果是引用数据类型,是值传递还是引用传递

其实大家被一堆术语给忽悠了,笔者画了2张图,帮助大家理解:

before change():

값이 Java에서만 전달되는 이유는 무엇입니까?

after change():

값이 Java에서만 전달되는 이유는 무엇입니까?

在Java中,除了基本数据类型以外,其他的都是引用类型,引用类型在内存中有两块存储空间(一块在栈stack中,一块在堆heap中)。

如果参数是引用类型,传递的就是实参所引用的对象在栈中地址值的拷贝,这里创建的副本是 地址的拷贝。那就有人说了,可是它值变了呀,这明明就是"引用传递"嘛?

我们可以换个角度理解,如果我们把栈地址当成值,会创建栈地址副本(复制栈帧),栈地址最终并没有改变,改变的是堆内存中的值。这就好比栈地址是钥匙,我们copy了一把,它能打开保险箱。我们关心的是钥匙有没有花纹这种变化,至于打开保险箱后的钱多钱少,我们并不需要关心。

虽然调用完函数后,str2变量值(堆中的数据)改变了,但是参数是引用类型,传递的实参是 栈中地址值,这是我们关心的,拷贝的是栈中地址值,最终栈中地址值并没有改变。所以是符合值传递的定义创建副本,不会影响原生对象。

可能又有人问了,那str变量值为啥没有改变呢?其实这完全是由于String类

이 문제에 대해 먼저 몇 가지 예를 보고 천천히 설명하세요.🎜

매개변수 전달 유형: 기본 데이터 유형

rrreee🎜결과:🎜
🎜param1 = 10
param2 = 20
변경 후 ....
param1 = 333
param2 = 444

==============

num1 = 10
num2 = 20🎜
🎜change() 메소드에서 변수를 재할당해도 변수 num1과 num2의 값은 변경되지 않는 것을 알 수 있습니다. 🎜변경되는 것은 복사본뿐입니다. Change() 메서드의 num1 및 num2입니다. 🎜기본 데이터 유형에는 메모리에 🎜스택🎜에 할당되는 저장 공간이 하나만 있다는 것을 알아야 합니다. 🎜🎜Java에서 전달하는 매개변수의 유형이 기본 데이터 유형인 경우 🎜값으로 전달🎜됩니다. 🎜🎜값이 Java에서만 전달되는 이유는 무엇입니까?🎜

매개변수 유형: 참조 데이터 유형

rrreee 🎜결과 : 🎜
🎜param1 = 샤오밍
param2 = 오늘 날씨 좋다
변경 후....
param1 = 샤오밍

param2 = 오늘 날씨 자, 낚시하러 가자

str = Xiao Ming
str2 = 오늘 날씨 좋다, 낚시하러 가자🎜
🎜str 변수는 변하지 않았지만, str2 변수가 변경되었습니다 여러분 헷갈리시죠? Java에서 전달되는 매개변수의 유형이 참조 데이터 유형인 경우 🎜pass by value🎜인가요 아니면 🎜pass by reference🎜인가요? 🎜🎜사실, 많은 사람들이 여러 용어에 속아왔습니다. 저자는 여러분의 이해를 돕기 위해 그림 2개를 그렸습니다: 🎜🎜변경 전():🎜🎜값이 Java에서만 전달되는 이유는 무엇입니까?🎜🎜변경 후():🎜🎜값이 Java에서만 전달되는 이유는 무엇입니까?🎜🎜Java에서는 기본 데이터 유형을 제외한 나머지는 모두 참조 유형입니다. 참조 유형은 메모리에 두 개의 저장 공간(스택에 하나, 힙에 하나)이 있습니다. 🎜🎜매개변수가 참조 유형인 경우 스택의 실제 매개변수가 참조하는 객체의 주소 값 복사본이 전달됩니다. 여기서 생성된 복사본은 주소의 복사본입니다. 그러면 누군가가 이렇게 말했는데, 그 값이 바뀌었다는 게 명백히 "참조에 의한 전달"인가요? 🎜🎜다른 관점에서 보면 스택 주소를 값으로 취급하면 스택 주소의 복사본이 생성됩니다(스택 프레임 복사). 결국 스택 주소는 변경되지 않습니다. 힙 메모리가 변경됩니다. 스택 주소가 열쇠인 것과 같습니다. 복사하면 금고를 열 수 있습니다. 우리가 관심을 갖는 것은 열쇠의 패턴에 변화가 있는지 여부입니다. 금고를 연 후 금액은 신경 쓸 필요가 없습니다. 🎜🎜함수를 호출한 후 str2 변수 값(힙의 데이터)이 변경되었지만 매개변수는 참조 유형이고 실제로 전달되는 매개변수는 스택의 주소 값입니다. 복사된 것은 스택의 주소 값입니다. 스택의 최종 주소 값은 변경되지 않았습니다. 따라서 복사본을 생성하는 것은 🎜가치 이전🎜의 정의를 준수하며 원본 개체에 영향을 미치지 않습니다. 🎜🎜누군가가 다시 질문할 수도 있습니다. str 변수 값은 왜 변경되지 않습니까? 사실 이는 전적으로 String 클래스의 특수한 특성 때문입니다. 이 때 함수의 param1= "Xiao Zhang"은 실제로 새 문자열을 생성합니다. 동시에 힙 메모리에 새로운 메모리 공간이 열리고 param1은 새로 열린 메모리 공간을 가리킵니다. 원래 주소 str이 가리키는 힙 메모리 공간의 데이터에는 변화가 없습니다. 🎜

위 내용은 값이 Java에서만 전달되는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제