Java 자바의 기초 (변수의 범위, 메소드, 접근제어자, static)

개발일지

이번 주는 자바에 대해 더 깊히 알 수 있었던 한 주였습니다. 다양한 내용들을 공부하면서 정리할 부분이 많아졌네요. 블로그에 내용을 정리하고 글을 쓰는 과정에서 복습도 되었고, 긍정적인 에너지를 느낄 수 있었습니다.

기본기를 탄탄하게 다져가며 한 발씩 앞으로 나아가려 합니다. 이번 글에는 변수의 범위, 접근 제어자, 메소드, 그리고 static에 대한 학습 내용을 간략하게 정리하여 담아보려 합니다.

변수의 범위

자바에서 변수의 범위(scope)는 변수가 어디에서 사용될 수 있는지를 나타냅니다. 다양한 변수의 범위가 있으며, 이를 이해하고 적절하게 활용하는 것이 프로그램의 가독성과 유지보수성을 높이는 데 중요합니다.

지역 변수 (Local Variables)

  • 선언 위치: 메서드, 초기화 블록, 루프 등 특정 코드 블록 내에서 선언됩니다.
  • 범위: 선언된 블록 내에서만 유효하며, 블록을 벗어나면 사용할 수 없습니다.
  • 생명 주기: 해당 블록이 실행될 때 생성되고, 블록의 실행이 종료되면 메모리에서 해제됩니다.
Java
public class LocalVariableExample {
    public void myMethod() {
        int localVar = 10; // 지역 변수
        System.out.println(localVar);
    }
}
Java

멤버 변수 (Instance Variables)

  • 선언 위치: 클래스의 인스턴스 영역에서 선언됩니다.
  • 범위: 클래스의 모든 메서드에서 사용 가능하며, 해당 클래스의 인스턴스가 존재하는 동안에 유지됩니다.
  • 생명 주기: 해당 클래스의 인스턴스가 생성될 때 생성되고, 인스턴스가 가비지 컬렉션의 대상이 될 때까지 메모리에 남아 있습니다.
Java
public class MemberVariableExample {
    int instanceVar = 50; // 멤버 변수

    public void myMethod() {
        System.out.println(instanceVar); // 인스턴스 메서드에서 접근 가능
    }
}
Java

클래스 변수 (Class Variables 또는 Static Variables)

  • 선언 위치: 클래스 수준에서 static 키워드를 사용하여 선언됩니다.
  • 범위: 클래스의 모든 메서드에서 사용 가능하며, 클래스가 로딩될 때 생성되고 프로그램이 종료될 때까지 유지됩니다.
  • 생명 주기: 프로그램이 시작될 때 한 번 생성되고, 프로그램이 종료될 때 메모리에서 해제됩니다.
Java
public class ClassVariableExample {
    static int classVar = 100; // 클래스 변수

    public static void main(String[] args) {
        System.out.println(classVar); // 클래스 메서드에서 접근 가능
    }
}
Java

매개변수 (Method Parameters)

  • 선언 위치: 메서드 정의 시 괄호 안에 선언됩니다.
  • 범위: 메서드 내에서만 사용 가능하며, 메서드 실행이 시작될 때 생성되고, 메서드 실행이 종료되면 메모리에서 해제됩니다.
  • 생명 주기: 메서드가 호출될 때 생성되고, 메서드 실행이 끝나면 소멸됩니다.
Java
public class ParameterExample {
    public void myMethod(int parameterVar) { // 매개변수
        System.out.println(parameterVar);
    }
}
Java

메소드

자바에서 메소드는 코드의 모듈화와 재사용성을 촉진하는 데 중요한 역할을 하는 프로그래밍 구성 요소입니다. 메소드는 특정 작업을 수행하는 코드 블록을 나타내며, 클래스 내에서 정의됩니다. 아래는 자바에서 메소드에 대한 자세한 설명입니다.

메소드 정의 (Method Declaration)

  • 메소드는 클래스 내에서 정의되며, 다음과 같은 구조를 갖습니다:
Java
[접근 제어자] [static] [리턴 타입] 메소드 이름([매개변수 목록]) {
    // 메소드의 기능 정의
    return 반환값;
}
Java

접근 제어자 (Access Modifiers)

  • 메소드의 접근을 제어하는 키워드로, public, private, protected, default 등이 있습니다.
  • public: 어떤 클래스에서든 접근 가능.
  • private: 동일한 클래스 내에서만 접근 가능.
  • protected: 동일한 패키지 내에서 및 하위 클래스에서 접근 가능.
  • (default): 동일한 패키지 내에서만 접근 가능.

static 키워드

  • 메소드가 정적(static) 메소드인 경우에 사용됩니다.
  • 정적 메소드는 객체의 인스턴스에 속하지 않고, 클래스 자체에 속합니다.
  • 인스턴스를 생성하지 않고도 클래스 이름으로 직접 호출할 수 있습니다.
Java
public static void printMessage() {
    System.out.println("Hello, Java!");
}
Java

리턴 타입 (Return Type)

  • 메소드가 실행을 완료한 후에 반환하는 값의 데이터 타입을 나타냅니다.
  • void는 반환값이 없음을 의미합니다.
Java
public int add(int a, int b) {
    return a + b;
}
Java

매개변수 (Parameters)

  • 메소드가 호출될 때 전달되는 값을 받기 위한 변수들입니다.
  • 매개변수는 메소드 정의에서 선언되며, 호출 시에 전달되는 값들이 해당 변수에 할당됩니다.
Java
public void printName(String name) {
    System.out.println("이름: " + name);
}
Java

반환 값 (Return Value)

  • 메소드가 실행을 완료한 후에 반환하는 값입니다.
  • return 키워드를 사용하여 반환값을 지정할 수 있습니다.
Java
public int add(int a, int b) {
    return a + b;
}
Java

메소드 호출 (Method Invocation)

  • 다른 코드에서 메소드를 실행하려면 해당 메소드를 호출해야 합니다.
  • 메소드 호출은 메소드 이름과 인자를 전달하는 괄호로 이루어집니다.
Java
int result = add(3, 5); // add 메서드 호출
Java

메소드 오버로딩 (Method Overloading)

  • 동일한 이름의 메소드를 여러 개 정의하는 것을 의미합니다.
  • 메소드의 매개변수의 개수나 타입을 다르게 함으로써 같은 이름의 메소드를 여러 개 가질 수 있습니다.
Java
public int add(int a, int b) {
    return a + b;
}

public double add(double a, double b) {
    return a + b;
}
Java

접근제어자

public

  • public 접근 제어자는 클래스, 변수, 메서드 등을 어디서든 접근 가능하게 합니다.
  • 다른 패키지의 클래스에서도 사용할 수 있기 때문에 주의가 필요합니다.
  • 대표적으로 API에서 제공되는 클래스나 메서드는 대부분 public입니다.

protected

  • protected 접근 제어자는 동일한 패키지 내의 클래스와 해당 클래스를 상속한 하위 클래스에서 접근 가능합니다.
  • 상속 관계에서 부모 클래스의 일부 기능을 하위 클래스에서 사용할 수 있도록 허용합니다.
  • 외부 패키지에서는 접근이 불가능하며, 클래스의 일부 구현을 외부에 노출하지 않습니다.

(default 또는 package-private)

  • default 접근 제어자는 특별한 키워드 없이 선언된 경우, 해당 패키지 내에서만 접근 가능합니다.
  • 클래스, 변수, 메서드 등에 별도의 접근 제어자를 명시하지 않으면 default로 간주됩니다.
  • 같은 패키지에 속한 클래스들끼리는 자유롭게 접근할 수 있습니다.

private

  • private 접근 제어자는 해당 클래스 내에서만 접근 가능하게 합니다.
  • 클래스 내부의 세부 구현을 숨기고 캡슐화를 통해 외부에서의 잘못된 접근을 방지합니다.
  • 다른 클래스에서 필요한 데이터는 해당 클래스에서 제공하는 메서드를 통해 접근할 수 있도록 합니다.

접근 제어자의 선택:

  • 적절한 접근 제어자의 선택은 정보 은닉, 캡슐화, 유지보수성 등을 고려하여 이루어져야 합니다.
  • 필요 이상으로 접근을 열어두면 코드의 의도와는 상관없이 외부에서 무분별한 조작이 가능해집니다.
  • 따라서 클래스의 멤버 변수는 주로 private으로 선언하고, 필요한 경우에만 getter와 setter 메서드를 제공하여 외부에서의 제어를 조절합니다.

접근 권한의 우선순위:

  • public -> protected -> (default) -> private 순서로 접근 권한이 부여됩니다.
Java
public class AccessModifiersExample {
    public int publicVar; // 어디서든 접근 가능
    private int privateVar; // 클래스 내에서만 접근 가능
    protected int protectedVar; // 동일 패키지 및 하위 클래스에서 접근 가능
    int packageVar; // (default) - 같은 패키지 내에서만 접근 가능
}
Java

💡접근 제어자의 범위를 한눈에 볼 수 있도록 표로 표현하겠습니다.

publicprotected(default)private
동일 클래스 내OOOO
동일 패키지 내OOOX
하위 클래스 내OOXX
전체 프로젝트 내OXXX
  • O: 접근 가능
  • X: 접근 불가능

static

static은 자바에서 특정 멤버(필드(변수), 메서드, 블록)를 클래스 레벨에 속하도록 지정하는 키워드입니다. static 멤버는 클래스의 인스턴스와는 독립적으로 존재하며, 여러 인스턴스가 해당 멤버를 공유합니다.

static 필드(변수)

  • static 키워드를 사용하여 정적 필드(변수)를 선언할 수 있습니다.
  • 모든 인스턴스가 해당 필드를 공유하며, 인스턴스 생성과 관계없이 클래스 이름으로 접근할 수 있습니다.
Java
public class MyClass {
    static int staticField = 10; // 정적 필드

    public static void main(String[] args) {
        MyClass obj1 = new MyClass();
        MyClass obj2 = new MyClass();

        System.out.println(obj1.staticField); // 클래스 이름으로 접근
        System.out.println(obj2.staticField);

        obj1.staticField = 20; // 모든 인스턴스가 공유하므로 값 변경 시 모든 인스턴스에 영향
        System.out.println(obj1.staticField);
        System.out.println(obj2.staticField);
    }
}
Java

static 메소드

  • static 키워드를 사용하여 정적 메소드를 선언할 수 있습니다.
  • 인스턴스 생성과 관계없이 클래스 이름으로 직접 호출할 수 있습니다.
Java
public class MyClass {
    static void staticMethod() {
        System.out.println("Static method");
    }

    public static void main(String[] args) {
        MyClass.staticMethod(); // 클래스 이름으로 직접 호출
    }
}
Java

static 중요 사항

  • static 멤버에서는 인스턴스 멤버에 직접 접근할 수 없습니다.
  • this 키워드를 사용할 수 없으며, super 키워드 역시 사용할 수 없습니다.
Java
public class MyClass {
    static int staticField = 10;
    int instanceField = 20;

    static void staticMethod() {
        // this.instanceField; // 에러: 정적 메소드에서 인스턴스 멤버에 직접 접근 불가
    }
}
Java

static 키워드를 올바르게 활용하면 클래스 레벨에서 공유되는 멤버를 효과적으로 사용할 수 있습니다. 그러나 지나치게 남발하면 객체지향 프로그래밍의 장점을 상실할 수 있으므로 적절한 상황에서 사용하는 것이 중요합니다.

마무리

이번 주는 자바에 대한 깊은 학습이 이뤄진 시간이었습니다. 다양한 주제들을 다루며 정리 작업이 많아지긴 했지만, 블로그에 글을 쓰고 있는 과정에서 지식을 복습하며 긍정적인 동기부여를 받았습니다.

변수의 범위, 메소드, 접근 제어자, 그리고 static에 대한 학습 내용을 정리하면서 기초적인 부분을 탄탄히 다지고 있다는 느낌을 받았습니다.

앞으로도 꾸준한 블로그 업데이트와 학습을 통해 지식을 더 쌓아가면서 성장해 나가겠습니다.🚀

Leave a Comment