-
210420_5~7_210421_1chapter11.(Call by value/reference, 문자열)JAVA(Sol)(정리대기중..언젠가) 2021. 4. 20. 16:01
클래스 멤버 메서드와 call by value
호출한다 값으로 ,즉 메서드를 호출할때 인자가 기본형 데이타인 경우
특징, 수신인자의 값을 바꾸어도 호출인자의 값에 영향이 없다.
이유 , 함수영역과 호출영역은 영역이 다르기 때문에 변수들간에 영향이 없다.
호출 즉 스택복사로만 값을 전달 할 수 있다.-------------------------------- 정의 영역
public int add (int a, int b) {
int c ;
c = a+b;
return c ; a = a;
} b = b; 전달행위를 스택복사 라고 한다
---------------------------------호출 영역
int a = 100 ;
int b = 200;
int c ;
c = add (a,b) ; // call by value : 인자가 기본형 변수일때
출력 ==> c ;
Call by reference
호출한다 레퍼런스값으로, 즉 함수를 호출할때 인자가 객체인 경우이다.
수신인자를 변경하면 호출인자도 같이 변경된다.
왜? 수신인자와 호출인자는 동일한 객체를 가리키기 때문이다
------------------------------------소스코드
class Hi{
int a ;
int b;
int c;
}
------------------------------------함수영역
public Hi add (hi) {
// hi.a=200; (hi.a가 200으로 바뀐다) // return때문에 호출영역의 hi.a가 변경된다.
hi.c = hi.a + hi.b ;
return hi;
}
------------------------------------호출영역
Hi hi = new Hi( );
hi.a=100;
hi.b=200;
add(hi); //호출인자 hi와 수신인자 hi가 동일한 hashCode 값을 가진다.
// 즉 같은 메모리 영역을 가리키게 된다.
sysout(hi.a)
------------------------------------heap
[a=100|b=200|c=300] <======= address --가공--> hashCode
// [a=200|b=200|c=400]
레퍼런스 값 ==> hashcode ==> 4byte정수(약 +/- 2억4천만 사이에서 발생)
-----------------------------------------------
package chapter11; class Pay1 { String name = ""; int pay = 0; int comm = 0; int tax = 0; public Pay1(String name, int pay, int comm) { this.name = name; this.pay = pay; this.comm = comm; comm = 100000; System.out.println("Pay1생성자 comm : " + comm); } public void tax() { tax = (int) (pay * 0.05); } public int earn() { int total = (pay + comm) - tax; return total; } } public class Employee { public static void main(String[] args) { String name = "아로미"; int pay = 1500000; int comm = 200000; System.out.println("comm변수의 초기값 : " + comm); Pay1 p = new Pay1(name, pay, comm); // call by value //String은 객체형이지만 인자로 사용되면 call by value로 작동한다 System.out.println("main 메소드 comm : " + comm); } }
package chapter11; class Pay2{ String name=""; int pay = 0; int comm =0; int tax = 0; public Pay2(String name, int pay, int comm) { this.name=name; this.pay=pay; this.comm=comm; } public int tax() { tax=(int)(pay*0.05); return tax; } public int earn() { int total = (pay+comm)-tax; return total; } } class PrintPay2{ public static void ptintPay(Pay2 pay) { // 객체를 가인자로 사용 System.out.println("------------------"); System.out.println("성명 : " + pay.name); System.out.println("본봉 : " + pay.pay); System.out.println("보너스 : " + pay.comm); System.out.println("세금 : " + pay.tax); System.out.println("실수령액 : " + pay.earn()); pay.tax=5000; System.out.println("-------------------"); System.out.println("pay.hashCode() : " + pay.hashCode()); } } public class Employee_args2 { public static void main(String[] args) { Pay2 p= new Pay2("왕눈이", 1000000,1000); // call by reference p.tax(); PrintPay2.ptintPay(p); // call by reference PrintPay2.ptintPay(p); System.out.println("p.hashCode() :" + p.hashCode()); } } //------------------ //성명 : 왕눈이 //본봉 : 1000000 //보너스 : 1000 //세금 : 50000 //실수령액 : 951000 //------------------- //pay.hashCode() : 366712642 //------------------ //성명 : 왕눈이 //본봉 : 1000000 //보너스 : 1000 //세금 : 5000 //실수령액 : 996000 //------------------- //pay.hashCode() : 366712642 //p.hashCode() :366712642
함수호출의 방식
call by value : 기본형 값을 인자로 호출하는 경우
call by reference : 객체 참조값, 즉 레퍼런스값을 인자로 호출하는 경우
즉 레퍼런스를 인자로 호출하는 경우(예외String)
예외.(일단암기)
String은 객체형이지만 인자로 사용되면 call by value로 작동한다
call by address: 주소값을 인자로 호출하는 경우 - 자바에서는 안나옴(C++에서만 사용)
210421_1
-------------------------------예1) ---(X) 메모리
String str1 = "홍길동"; 실행 --------->홍길동
String str2 = "홍길동"; --------->홍길동
--------------------------------
-------------------------------예2) ---(O) 메모리
String str1 = "홍길동"; 실행 -------->홍길동
String str2 = "홍길동"; ---------> ---↑
str1 == str2 : True
--------------------------------
문자열은 상수이므로 메모리 상에 동일한 상수는 한번만 존재한다.
-------------------------------예3) 메모리
String str1 = "홍길동"; 실행 ------------------------------>홍길동
String str2 = "홍길동"; --------->----------------------↑
String str3 = new String("홍길동");----->[heap]해쉬코드->---↑
str1 == str2 : True
str1 == str3 : False
str1 equals(str2) : True <=== equals()는 순수문자열을 비교한다.
str1 equals(str3) : True
str1 해쉬코드 : 12345
str2 해쉬코드 : 12345
str3 해쉬코드 : 12345
결론 1.문자열은 == (등치연산자)로 비교하지말것., equals()메서드로 비교한다.
2.문자열은 영역에 상관없이 같은 문자열이면 해쉬코드는 언제나 동일하다.
-------------------------------예4) 메모리
String str1 = "홍길동"; 실행 --------->홍길동 + 킹 + 왕 + 짱-----(1) (X) 상수는 메모리 연장안됨
String str1 +="킹";
String str1 +="왕";
String str1 +="짱";
str1 => "홍길동킹왕짱"
홍길동--------(2) (O) 바꿀수 없으니 새로운 상수를 계속 만들어낸다.
홍길동킹
홍길동킹왕
홍길동킹왕짱
--------------------------------
결론 3. 문자열이 바뀌면 해쉬코드도 무조건 바뀐다,
4.그래서 문자열이 자주 바뀌면 String을 사용하지 않는다.
대신에, StringBuffer 나 StringBuilder를 사용한다.
------code
class 코드영역
-------data
static 상수영역 정적영역
--------------------------------method area
-------heap
객체영역 gc대상영역:가끔수거
-------stack
메서드실행영역 자동수거, 바로수거됨
package chapter11; class GenClass { private String name; private int num; // String을 인자로 사용하는경우 public GenClass(String a, int b) { name = a; num = b; } public void rename(String a) { String str = a; System.out.println("\nrename()--------------------"); // 출력순서2 System.out.println("rename() : " + str); System.out.println("rename() a.hashCode : " + str.hashCode()); str = "★" + str; System.out.println("\nrename()문자열변경-----------"); // 출력순서3 System.out.println("rename() : " + str); System.out.println("rename() a.hashCode : " + str.hashCode()); } } public class NonThread { public static void main(String[] args) { GenClass t1 = new GenClass("first", 1); String sc = "대~한~민국"; System.out.println("\nmain()--------------------"); //출력순서1 System.out.println("main() sc:" + sc); System.out.println("sc.hashCode : " + sc.hashCode()); t1.rename(sc); // call by value이기때문에 sc= "대~한~민국"으로 돌아온다 System.out.println("\nmaint() rename(sc)후--------"); //출력순서4 System.out.println("main() sc:" + sc); System.out.println("sc.hashcode : " + sc.hashCode()); } } // //main()-------------------- //main() sc:대~한~민국 //sc.hashCode : -612571759 // //rename()-------------------- //rename() : 대~한~민국 //rename() a.hashCode : -612571759 // //rename()문자열변경----------- //rename() : ★대~한~민국 //rename() a.hashCode : 281523158 // //maint() rename(sc)후-------- //main() sc:대~한~민국 //sc.hashcode : -612571759
'JAVA(Sol)(정리대기중..언젠가)' 카테고리의 다른 글
210421_3(garbageCollecting) (0) 2021.04.21 210421_2(접근제한자) (0) 2021.04.21 210420_3~4(변수 유효범위,생성자특징) (0) 2021.04.20 210420_1~2(static변수,singleton pattern,final) (0) 2021.04.20 210419_7~8 (생성자오버로딩) (0) 2021.04.19