ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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
    
Designed by Tistory.