Programming Lang/Java

[Java] Variable, Method, JVM

haema_dev 2022. 9. 5. 00:13

변수와 메서드란?

variable (변수)
something that is variable
method (메서드, 방법)
a procedure or process for attaining an object
- a way, technique, or process of or for doing something

 

ETC

static 스태틱 (정적인) : standing or fixed in one place
instance : 어떤 집합에 대해서, 그 집합의 개별적인 요소
class : 수업, 과목, 반, 학급 등

 

변수의 종류

  1. 클래스 변수
  2. 인스턴스 변수
  3. 지역 변수

 

변수의 선언된 위치가 중요!

class VarMethod {
    void main(String[] args) {
        Variables.cv = 0;
        //Variables.iv = 0; 
        //Cannot make a static reference to the non-static field Variables.iv
    }
}

class Variables { // 클래스 영역
    int iv = 1;   // 2. 인스턴스 변수
    static int cv = 5;   // 1. 클래스 변수 (static 변수, 공유변수)
    // **전역(global) 변수와는 다름!!

    void method() { // 메서드 영역
        int lv = 0;   // 3. 지역 변수
    }
}

클래스 변수, 인스턴스 변수, 지역 변수

더보기

class VarMethod {

    void main(String[] args) {

        Variables.cv = 0;

        //Variables.iv = 0; 

        //Cannot make a static reference to the non-static field Variables.iv

    }

}

 

class Variables { // 클래스 scope

    int iv = 1;   // 2. 인스턴스 변수

    static int cv = 5;   // 1. 클래스 변수 (static 변수, 공유변수) 

    // **전역(global) 변수와는 다름!!

 

    void method() { // 메서드 scope

        int lv = 0;   // 3. 지역 변수

    }

}

 

변수

인스턴스 변수

  • 클래스 영역에 선언
  • 클래스의 인스턴스 생성 시, 생성
  • 인스턴스를 생성해야만 사용 가능
  • 독립적인 저장공간(변수)을 가진다   => 만들때마다 객체 생성
  • 서로 다른 값을 가질 수 있다
  • 각 인스턴스마다 고유한 상태를 유지해야하는 속성

 

클래스 변수

  • 인스턴스 변수 앞에 static을 붙인다.
  • 인스턴스를 생성하지 않고도 사용 가능
  • 공통된 저장공간(변수)을 공유한다
  • 각 인스턴스들이 공통적인 값을 유지해야하는 속성
  • 클래스(참조변수 동일)가 메모리에 ‘로딩(loading)’될 때 생성되어 프로그램 종료까지 유지
  • main method 앞에 public static 을 붙이면 다른 클래스의 클래스 변수에 접근 가능   => 프로그램 내 어디서나 접근 가능한 전역 변수(global variable) 성격을 가진다.

 

지역 변수

  • 메서드 내 선언
  • 메서드(반복문 스코프, 함수, 생성자 및 초기화 블럭 포함) 내에서만 사용 가능
  • 메서드가 종료 시 소멸
  • 블럭{} 내에 선언된 지역변수는 해당 scope 안에서만 사용 가능

 

class MethodHeaderBody {

    private static int a = 10;
    private static int b = 5;

    public static void main(String[] args) {

        Add add = new Add(a, b);
        int result = add(a, b);

        System.out.println("==객체생성x 사용(static)==");
        System.out.println(result);
        System.out.println(add(a, b));

        System.out.println("==객체생성 후 사용==");
        System.out.println(add);
        System.out.println(add.AddResult(a, b));
    }

    // 메서드 호출 시, 실행을 잠시 멈추고 메서드의 문장들이 실행 후, 끝나면 기존 실행 진행
    public static  int  add(int a, int b) {
        //반환은 한 개의 값일 수도, array나 map 같은 collection 일 수도 있다.
        return a+b;  // 반환문 int 위치 void 올 경우 삭제
    }
}

public class Add {
    public Add(int a, int b) {} // 생성자
    
    public int AddResult(int a, int b) {
        a = 1;
        b = 2;
        return a+b;
    }
}

 

 

JVM 메모리 구조

  1. method area (=static memory)
  2. heap memory
  3. stack memory

 

◆ 메서드 영역, 스태틱 메모리 (컴파일 과정에서 사용되는 메모리)

  • 바이트 코드 및 컴파일 되면서 생기는 클래스 파일(.class 파일), 클래스 변수
  • 원시형 및 리터럴 값(실데이터)

 

◆ 힙 메모리 (런타임 과정에서 사용되는 메모리)

  • 인스턴스 변수
  • 참조 주소

 

◆ 스택 메모리 (작업이 끝나면 종료)

  • 메서드 실행 시 (main 포함)
  • 지역변수 (매개변수 포함)
  • 메서드 실행 시, 연산의 중간결과 등

 

 

기본형 매개 변수와 참조형 매개변수

  • 기본형 매개변수 : 변수의 값을 읽기만 가능 (read only)
  • 참조형 매개변수 : 변수의 값을 읽고 변경 가능 (read & write)

 

원본이 아닌 복사본 변경

//기본형 매개변수
class Data1 {
	int x;
	//static int x = 10;
	//final int x = 10;
}

public class PrimitiveParamEx {
    public static void main(String[] args) {

        Data1 d = new Data1();
        d.x = 10; //The final field Data1.x cannot be assigned
        System.out.println("main() : x = " + d.x);

        change(d.x);
        System.out.println("After change(d.x)");
        System.out.println("main() : x = " + d.x);
    }

    static void change(int x) {
        x = 1000;
        System.out.println("change() : x = " + x);
    }
}

// 결과는 10

값이 저장된 주소의 데이터를 변경

//참조형 매개변수
class Data2 { int x; }

public class ReferenceParamEx {
    public static void main(String[] args) {

        Data2 d = new Data2();
        d.x = 10;
        System.out.println("main() : x = " + d.x);

        change(d);
        System.out.println("After change(d)");
        System.out.println("main() : x = " + d.x);
    }

    static void change(Data2 d) {    // 참조형 매개변수(클래스)를 넘겨줌.
        d.x = 1000;
        System.out.println("change() : x = " + d.x);
    }
}

// 결과는 1000 (값이 변경된다.)

그러므로, 값이 ‘복사(copy)’ 되는 건 기본형 매개변수이다.

 

 

참조형 반환타입

  •  return 타입이 참조형이라는 것은 주소를 반환한다는 의미
  •  새로운 주소를 생성하여 복사한다
  •  새로운 주소를 생성했다는 것은 새로운 객체가 생겼다는 의미

 

참조형 반환타입

class Data {int x;}

public class ReferenceReturnEx {
    public static void main(String[] args) {

        Data d = new Data();
        d.x = 10;

        Data d2 = copy(d);
        System.out.println("d.x="+d.x);
        System.out.println("d2.x="+d2.x);
    }

    static Data copy(Data d) {

        Data tmp = new Data();
        tmp.x = d.x;
        return tmp;
    }
}

 

 

Q.  static 과 final 의 차이는?

A.  목적이 다르다.

 

static

  • 객체생성 없이 사용하기 위함이다.
  • 재사용성(공유 값 사용) 때문이다.

  

final

  • 고정된 값(수치)이 필요. 변경될 시, 문제가 생길 여지 자체를 아예 제거한다.  (ex> final int PIE = 3.14)
  • 굳이 고정데이터를 변수에 담는 이유는 개발자가 알아보기 쉽기 위함이다.

 

더보기

참고자료 : 자바의 정석, 자바의 신

(+ 개인 생각)