전체 커리큘럼
상세 커리큘럼
진행률; 백엔드 시작 - 스프링 입문
Call by value
와 Call by reference
란 원시 타입이나 객체 타입이 **함수의 인자(argument)**로 할당 받고 **매개변수(parameter)**로 전달될 때 어떤 방식으로 전달될 지를 결정하는 방식이다.
Parameter; Argument;
출처; https://chitru-shrestha.medium.com/argument-and-parameter-in-javascript-with-examples-14405c8c8757
Value와 Reference의 차이점을 알아보기 전에 가장 먼저 알아야 할 것이 하나 있다. 인자(Argument)와 매개변수(Parameter) 정의와 차이점을 아는 것이다.
Parameter; 매개변수는 함수(or 메서드)를 정의할 때, 외부에서 입력 받을 값으로써 함수의 Body에서 동작을 정의할 때 사용되는 임의 값을 표현하는 변수를 의미한다.
Argument; 인자는 함수를 호출할 때, 실제로 사용되는 값을 말한다.
JS
결론부터, 말하면 JS는 무조건 Call by Value 방식이다.
값에 의한 전달(Call by Value)
원시 타입 ⇒ string, boolean, number(int), long (클래스 or 배열을 제외한 모든 타입)
let str = 'javascript';
function test1(st){
st = 'hello';
console.log(st);
};
console.log(str); // Output1 : ??
test1(str); // Output2 : ??
console.log(str); // Output3 : ??
let st = str;
st = 'typescript';
console.log(str); // Output1 : ??
console.log(st); // Output2 : ??
원시타입의 값은 메모리에 **원시 값(Nature Value)**이 저장된다.
test1
함수의 인자(Argument)로 str 변수를 할당하면 함수의 매개변수(Parameter, st)에 str 변수의 값이 복사 된다.
원시 값을 갖는 변수(str)를 다른 변수에 할당하면 원시 값이 복사되어 전달된다. 이것을 우리는 값에 의한 전달이라고 말한다.
let a = 1;
// 0x1234 => 1
let b = a;
// 0x5678 => 1
한번 메모리 공간에 저장한 원시 값은 변경 불가능한 값이다.
참조에 의한 전달(Call by Reference)
객체 타입(+ Array)
객체 타입의 값은 변경 가능하다.
객체를 변수에 할당하면 변수에 확보된 Stack 메모리 공간에는 참조 값(Heap Memory Addrss)이 저장된다.
아래 예제처럼 다른 변수에 객체를 가리키고 있는 변수를 할당하면 값이 저장되는 것이 아니라, 원본 객체의 참조 값이 저장된다.(얕은 복사)
즉, Call by Value 형태로 값이 전달된다. 하지만 원시형 타입과 다르게, 원본 데이터의 영향을 미치는 이유는 원시 값을 복사하는 것이 아니라 객체의 값이 저장되어 있는 메모리 주소를 복사하기 때문에 영향이 있는 것이다.
그렇기 때문에 원본 또는 복사본에 데이터 추가/수정/삭제 된다면 모든 객체(원본 및 복사본)에 영향을 미친다.
function cbr(obj2){
obj2.a = 'change';
console.log(obj2);
};
function cbr1(obj2){
obj2 = obj2.a = 'change'; // 가장 우측부터 할당, obj2.a = 'change'; and obj2 = 'change';
obj2.b = 'add';
console.log(obj2);
};
let obj1 = {
a: 1
};
cbr(obj);
console.log(obj1);
cbr(obj1);
console.log(obj1);
let car = {
color: 'red', // stack - 0x12349876 ---> Heap
}; // Heap 메모리 x번 해당 객체를 저장하고, Stack 메모리 2번에 x번 주소값을 저장.
let secondCar = car;
secondCar.color = 'blue';
car.wheel = 4;
console.log(car); // output: {color: 'blue', wheel: 4}
console.log(secondCar); // output: {color: 'blue', wheel: 4}
console.log(car == secondCar); //output: true
console.log(car === secondCar); //output: true
그렇다면 원본 객체와 동일한 데이터를 가지지만, 영향을 받지 않는 객체를 복사할 수는 없는가?
깊은 복사를 통해서 생성할 수 있다.
새로운 객체를 Heap 메모리에 생성하고, 그 주소를 변수에 저장하면 된다.
let car = {
color: 'red',
};
let secondCar = Object.assign({}, car); // 방법1. assign 메소드
let thirdCar = {...car}; // 방법2. spread 연산자
car.wheel = 4;
secondCar.color = 'blue';
console.log(car); // output: {color: 'red', wheel: 4}
console.log(secondCar); // output: {color: 'blue'}
console.log(car == secondCar); //output: false
console.log(car === secondCar); //output: false
JAVA
자바의 데이터 타입(Type)
자바에서는 데이터 타입(Data Type)을 크게 2가지로 카테고리로 구분 한다.
기본형(primitive type)
boolean
), 문자형(char
), 정수형(short
, byte
, int
, long
), 실수형(float
, double
)참조형(reference type)
String
, ), Interface Type, Collection Framework(ex. List
, Set
, Map
), Enum Type, etc.예제 코드
package org.coding.test.data.structure.delivery.value;
public class Example1 {
static void addByValue(int a){
a += 100;
}
static void addByReference(int[] a){
a[0] += 100;
}
public static void main(String[] args) {
int x = 10;
int[] y = {1};
addByValue(x);
System.out.println("Add By Value - Output ::: " + x);
addByReference(y);
System.out.println("Add By Reference - Output ::: " + y[0]);
}
}
재귀 호출