우리는 기본적으로 값으로 전달하는 방법과 참조로 전달하는 두 가지 방법이 있다는 것을 알고 있습니다. 그러면 JAVA에서는 값으로 전달합니까 아니면 참조로 전달합니까? 다음 글에서 이를 소개하겠습니다. 도움이 되셨으면 좋겠습니다.
값 전달: 함수 호출 시 실제 매개변수의 복사본을 복사하여 형식 매개변수에 전달하여 함수 내 형식 매개변수를 수정해도 값에 영향을 미치지 않도록 하는 것을 말합니다. 실제 매개변수.
Pass by reference: 함수 호출 시 실제 매개변수의 주소를 형식 매개변수에 직접 전달하는 것을 말합니다. 그러면 함수에서 매개변수를 수정하면 실제 매개변수의 값에 영향을 미칩니다.
Java에서 값을 전달하는 방법은 무엇입니까?
Java의 값 전달 방법: 값 전달(모든 변경 사항은 메서드 본문으로만 제한되며, 메서드 본문 외부에서는 수정 작업이 더 이상 유효하지 않습니다.) [추천 학습: java 강좌]
Java에는 값 전송만 있는지 확인하는 프로그램을 사용할 수 있습니다
/** * 验证java中只有值传递 */ class User{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }public class TestValue { public static void change(User user2,int a2){ System.out.println("改变之前:"+user2.getName()+",a2="+a2); user2.setName("李四"); //改变 user2 的 name 值 a2 = 10; //改变 a2 的值 System.out.println("改变之后:"+user2.getName()+",a2="+a2); user2 = new User(); //将 user2 重新指向一个新对象 user2.setName("王五"); System.out.println("重新指向一个新对象后:"+user2.getName()); } public static void main(String[] args){ User user1 = new User(); user1.setName("张三"); //初始化 user1 的 name 为张三 int a1 = 5; //初始化 a1 的值为 5 change(user1,a1); //调用方法验证传值方式 System.out.println("调用方法后:"+user1.getName()+",a1="+a1); } }
이 프로그램을 실행하면 출력 결과는 다음과 같습니다.
改变之前:张三,a2=5 改变之后:李四,a2=10 重新指向一个新对象后:王五 调用方法后:李四,a1=5
결과 분석
위 그림을 이 프로그램을 분석하는 데 도움이 되도록 사용하겠습니다. 먼저 User
클래스를 정의한 다음 테스트 클래스에서 User
개체를 인스턴스화합니다. user1
로 이름을 지정하고 name = 'Zhang San'을 할당합니다.
User
类,然后在测试类中实例化了一个User
对象,名为user1
,并且为其赋值name = '张三'。
此时在内存中如图1
所示,实例化一个对象相当于在堆中开辟了一块内存,内存地址为017
,此时这个对象的引用为user1
,内存地址为001
,它保存了该对象在内存中的地址,也就是指向了该对象。
接下了,我们调用方法change()
,来尝试改变user1
的name
值以此验证java中的传值方式。
我们将user1
作为实参传给change()
方法,形参user2
来接受这个实参,在这里就体现出了两种传参方式的不同。如果是按值传递,那么就像定义的那样。
如图2
所示,user2
是user1
的一份副本,也就是说在传递参数时,将user1
(本身是一个对象的引用),复制了一份,名为user2
,它同样也是一个对象的引用,并且user1
和user2
此时指向同一个对象。
而如果是引用传递,也如同定义的那样,如图5
所示,在传递参数时,是直接将user1
传递给了形参,只是换了一个名字叫做user2
,但是本质上user1
和user2
其实是同一个。它是一个对象的引用。
接着来分析输出的结果,不管是按值传递还是引用传递,第1行输出的结果一定都是张三
,因为都是指向同一个对象。对于第2行输出,我们还是无法判断是哪种方式,因为都是改变同一个对象,值也会改变;关键在于第3行输出和第4行输出。
此时,我们将user2
重新指向了一个新的对象,并且为这个对象赋值name = '王五'
,如果是引用传递的方式,那么user1
同样也会改变指向,指向新的这个对象,最后一行调用方法之后输出的结果将会和第3行一样是王五
,但是事实输出的是李四
。这表明user1
和user2
其实并不是同一个。
真实的调用过程如 图2
~图4
所示,这样才会使得user2
指向一个新的对象后,user1
指向的对象并没有改变,还是原来那个对象。
对于基本类型的参数来说,a1
的值最后没有改变,说明在执行方法时,a2
是a1
的一个副本。
对于引用类型的参数来说,例如User
对象,在调用方法时,实际上是将其引用user1
作为实际参数,那么传递给形参的将是该引用的一份副本引用user2
,虽然说这是两份引用(好比a1
与a2
그림 1
과 같이 객체를 인스턴스화하는 것은 힙에서 메모리 조각을 여는 것과 동일하며 메모리 주소는 입니다. 017
. 이때 이 개체의 참조는 user1
이고, 메모리 주소는 001
입니다. 대상을 가리킨다는 뜻이다. 이후 change()
메소드를 호출하여 user1
의 name
값을 변경하여 Java의 값 전송 방법을 확인합니다. . 여기에 표시된 것처럼 user1
을 change()
메서드에 실제 매개변수로 전달하고 형식 매개변수 user2
는 이 실제 매개변수를 받아들입니다. 두 가지 매개변수 전달 방식의 차이점이 드러납니다. 값으로 전달되면 정의된 대로입니다. 그림 2
에 표시된 것처럼 user2
는 user1
의 복사본입니다. 즉, 매개변수를 전달할 때 user1
(그 자체는 개체에 대한 참조), 개체에 대한 참조이기도 한 user2
라는 복사본을 만들었고, user1
및 user2
이제 동일한 객체를 가리킵니다.
그림 5
와 같이 정의된 대로 매개변수 전달 시 user1
이 형식 매개변수에 직접 전달되지만 이름이 user2
로 변경되었지만 본질적으로 user1
과 user2
는 실제로 동일합니다. 객체에 대한 참조입니다. 다음으로 출력 결과를 분석해 보겠습니다. 값으로 전달되든 참조로 전달되든 1행의 출력 결과는 모두 동일한 개체를 가리키므로 Zhang San
이어야 합니다. 2행의 출력에서는 동일한 객체가 변경되고 값도 변경되기 때문에 어떤 메서드가 사용되는지 알 수 없습니다. 핵심은 3행과 4행의 출력에 있습니다.
user2
를 새 객체로 리디렉션하고 이 객체에 name = '王五'
를 할당합니다. 참조로 전달되면 입니다. >user1
도 포인터가 새 개체를 가리키도록 변경합니다. 마지막 줄에서 메서드를 호출한 후의 출력 결과는 세 번째 줄인 王五
와 동일하지만 사실 출력은 John Doe
입니다. 이는 user1
과 user2
가 실제로 동일하지 않음을 나타냅니다. 🎜🎜실제 호출 프로세스는 그림 2
~그림 4
와 같습니다. 그러면 user2
가 새 개체인 user1
가 가리키는 개체는 변경되지 않았으며 여전히 동일한 개체입니다. 🎜🎜기본 유형 매개변수의 경우 a1
의 값은 마지막에 변경되지 않습니다. 이는 메소드가 실행될 때 a2
가 a1 . 🎜🎜 <code>User
객체와 같은 참조 유형 매개변수의 경우 메소드를 호출할 때 실제로 user1
을 실제 매개변수로 참조한 다음 값이 형식 매개변수에 전달됩니다. 이는 두 개의 참조(예: a1
와 a2
사이의 관계))이지만 user2
를 참조하는 참조의 복사본입니다. 🎜🎜하지만 동일한 개체를 가리키며 모든 작업은 동일한 개체에 대한 것입니다. 🎜🎜🎜🎜에필로그🎜🎜🎜🎜위의 분석을 통해 알 수 있습니다. 🎜Java🎜에서 값을 전달하는 방법은 한 가지뿐이지만 참조 유형의 경우 전달된 매개변수는 객체에 대한 참조입니다. 🎜위 내용은 Java에서 값을 전달하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!