오늘의하루

[자바의 정석] 변수와 메소드 & 메소드 오버로딩 & JVM 구조 본문

JAVA

[자바의 정석] 변수와 메소드 & 메소드 오버로딩 & JVM 구조

오늘의하루_master 2022. 10. 14. 11:46

변수와 메소드

변수는 선언위치에 따라 종류와 범위(Scope)가 달라진다.

class Variables{ // Class Area Start
    int iv; // 인스턴스 변수
    static int cv; // 클래스 변수
    
    void method(){ // Method Area Start
        int lv = 0; // 지역 변수
    } // Method Area End
} // Class Area End

변수의 종류

변수의 종류 선언 위치 생성 시기
클래스 변수 클래스 영역 클래스가 메모리에 올라갈때
인스턴스 변수 인스턴스가 생성될때
지역 변수 메소드 영역 메소드가 호출되었을때

변수의 특징

  1. 클래스 변수
    • 같은 클래스의 모든 인스턴스들이 공유하는 변수이다.
    • 인스턴스 생성없이 " 클래스명.클래스변수명 "으로 접근이 가능하다.
    • 클래스가 메모리에 올라갈때 생성되고 프로그램이 종료될때 소멸한다.
  2. 인스턴스 변수
    • 각 인스턴스의 개별적인 저장공간이며 인스턴스마다 다른 값을 저장할 수 있다.
    • 인스턴스 생성 후 " 참조변수.인스턴스변수명 "으로 접근이 가능하다.
    • 인스턴스가 생성될때 생성되며 참조변수가 없을 때 가비지 컬렉터에 의해 자동 제거된다.
  3. 지역 변수
    • 메소드 내에 선언되며 메소드 종료와 함께 소멸된다.
    • 조건문, 반복문의 블럭 "{}" 내에 선언된 지역변수는 블럭을 벗어나면 소멸된다.

메소드

메소드는 오로지 클래스 영역에서만 정의 할 수 있다.

리턴타입 메소드명 (타입 변수명1, 타입 변수명2 ...) => 선언부
{ => 구현부
    // 메소드 호출 시 수행될 코드
}
// Example
int add (int a, int b)
{
    int result = a + b;
    return result;
}

return 문

메소드가 정상적으로 종료되는 경우에는 2가지가 있다.

  • 메소드의 블럭 "{}"의 끝에 도달했을때
  • 메소드의 블럭 "{}"을 수행 도중 return문을 만났을때
    • 현재 실행 중인 메소드를 종료하고 호출한 곳 반환값을 돌려준다.
1. 반환값이 없는 경우는 "return;" 으로 작성하면 된다.
2. 반한값이 있는 경우는 "return 반환값;" 으로 작성하면 된다.
// Example
int add (int a, int b){
    int result = a + b;
    return result;
}
// 선언부의 리턴타입과 구현부에 있는 리턴의 반환값 타입은 일치해야한다.

메소드의 종류

  1. 인스턴스 메소드
    1. 인스턴스 생성 후 "참조변수.메소드명(매개변수)"로 호출이 가능하다.
    2. 인스턴스 변수나 인스턴스 메소드와 관련된 작업을 한다.
    3. 메소드 내에서 인스턴스 변수, 클래스 변수가 사용 가능하다.
    4. 메소드 내에서 인스턴스 메소드, 클래스 메소드 호출이 가능하다.
  2. 클래스 메소드
    1. 인스턴스 생성 없이 "클래스명.메소드명(매개변수)"로 호출이 가능하다.
    2. 인스턴스 변수나 인스턴스 메소드와는 관련 없는 작업을 한다.
    3. 메소드 내에서 인스턴스 변수는 사용이 불가능하다.
    4. 메소드 내에서 클래스 메소드는 호출 가능하지만 인스턴스 메소드 호출은 불가능하다.
class TestClass{
    int iv = 1;
    static int cv = 2;
    void instanceMethod(){}
    static void staticMethod(){}
    
    void instanceMethod2(){
        System.out.println(iv); // 인스턴스 변수 사용 가능( 결과 : 1 )
        System.out.println(cv); // 클래스 변수 사용 가능( 결과 : 2 )
        instanceMethod(); // 인스턴스 메소드 호출 가능
        staticMethod();   // 클래스 메소드 호출 가능
    }
    
    static void staticMethod2(){
        System.out.println(iv); // 실패! 인스턴스 변수 사용 불가능
        System.out.println(cv); // 클래스 변수 사용 가능 ( 결과 : 2 )
        instanceMethod(); // 실패! 인스턴스 메소드 호출 불가능
        staticMethod();   // 클래스 메소드 호출 가능
    }
}

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

각각의 매개변수의 특징에 대해 알아보자

  • 기본형 매개변수
    • 변수의 값을 읽기만 가능하다. (read)
  • 참조형 매개변수
    • 변수의 값을 읽기 및 변경이 가능하다. (read & write)
public class Test{
    public static void main(String[] args){
        Data d1 = new Data();
        Data d2 = new Date();
        
        d1.x = 10;
        d2.x = 20;
        System.out.println("main() : x = " + d1.x); // 결과 10
        System.out.println("main() : x = " + d2.x); // 결과 20
        
        change1(d1.x); // 기본형 매개변수
        System.out.println("After change1(d1.x)");
        System.out.println("main() : x = " + d1.x); // 결과 10
        
        change2(d2); // 참조형 매개변수
        System.out.println("After change2(d2");
        System.out.println("main() : x = " + d2.x); // 결과 200
    }
    static void change1(int x){
        x = 100;
        System.out.println("change1() : x = " + x); // 결과 100
    }
    
    static void change2(Data d){
        d.x = 200;
        System.out.println("change2() : x = " + d.x); // 결과 200
    }
}

class Data{
    int x;
}

메소드 오버로딩

하나의 클래스에 같은 이름의 메소드를 여러 개 정의하는 것을 메소드 오버로딩이라고 한다.

오버로딩을 하는 이유는 매개변수는 다르지만 같은 의미의 기능을 수행하는 메소드를 만들기 위함이다.

오버로딩의 조건

  1. 메소드의 이름이 같아야한다.
  2. 매개변수의 개수 또는 타입이 달라야한다.
  3. 리턴 타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.
class Test{
    int add(int a, int b){return a + b;}
    long add(long a, long b){return a + b;}
    long add(int a, long b){return (long)(a + b);}
    long add(int a, int b){return (long)(a + b);} // Error! 매개변수가 같다.
}

JVM의 메모리 구조

Java Virtual Machine의 줄임말로 Java를 OS에 종속되지 않게 만들기 위해 만들어진 것이다.

  • OS에 종속받지 않고 CPU가 Java를 인식하고 실행할 수 있게 해주는 가상 컴퓨터이다.

Java 소스코드(*.java)는 CPU가 인식을 하지 못하기 때문에 원래는 기계어로 컴파일을 해줘야 하지만 Java는 JVM이라는 가상 컴퓨터를 통해 인식 및 실행되기 때문에 JVM이 인식할 수 있는 bytecode(*.class)로 변환해줘야 한다.

이렇게 변환된 bytecode는 기계어가 아니기 때문에 여전히 OS에서는 바로 실행되지 않는다.

하지만 이때 JVM이 해당 OS가 bytecode를 이해 할 수 있도록 해석을 해준다.

JVM의 동작과 구조

JVM 구조는 크게 Garbage Collector, Execution Engine, Class Loader, Runtime Data Area 이렇게 4가지로 나눌 수 있습니다.

Java-virtual-machine

  • Class Loader
    • JVM 내로 클래스 파일을 로드하는 모듈이며 런타임 시에 동적으로 클래스를 로드한다.
  • Excution Engine
    • Class Loader를 통해 JVM 내의 Runtime Data Area에 배치된 byte code들을 명령어 단위로 읽어서 실행한다.
  • Garbage Collector
    • Heap Area에 생성된 객체들 중에서 참조되지 않는 객체들을 탐색 후 제거 하는 역할을 한다.
  • Method Area
    • 모든 쓰레드가 공유하는 메모리 영역이다.
    • 클래스, 인터페이스, 메소드, 필드, Static 변수 등의 바이트 코드를 보관한다.
  • Heap Area
    • 모든 쓰레가 공유하는 메모리 영역이다.
    • new 연산자로 생성된 객체와 배열이 생성되는 영역이다.
    • Garbage Collector가 참조되지 않는 메모리를 확인하고 제거하는 영역이다.
  • Stack Area (Last In First Out)
    • 메소드 호출 시마다 각가의 스택 프레임을 생성된다.
    • 메소드 안에서 사용되는 값을 저장하고 호출된 메소드의 매개변수, 지역변수, 리턴값 및 연산 시 일어나는 값들을 임시로 저장한다.
    • 메소드 수행이 종료되면 프레임 별로 삭제된다.
  • PC Register
    • 쓰레드가 시작할 때 생성된다.
    • 쓰레드마다 하나씩 존재한다.
    • 쓰레드가 어떤 부분을 무슨 명령으로 실행해야 할지에 대한 기록 하는 부분으로 현재 수행중인 JVM 명령의 주소를 갖는다.
  • Native method stack
    • 자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역이다.
Comments