멤버 = 필드 + 메서드
- 선언하는 방법에 따라서 인스턴스 멤버와 클래스 멤버로 구분
- 인스턴스 멤버는 객체 생성 후에 사용 가능
- 클래스 멤버는 객체 생성 없이도 사용 가능
인스턴스 멤버
객체의 인스턴스 필드는 각각의 인스턴스마다 고유하게 값을 가질 수 있음
하지만 그렇다고 각 인스턴스 마다 메서드들이 매 번 생성된다면 중복 저장으로 메모리 효율이 떨어짐
→ 메서드는 메서드 영역에 두고서 모든 인스턴스들이 공유해서 사용
→ 대신 무조건 객체 생성, 즉 인스턴스를 통해서만 메서드가 사용될 수 있도록 제한
클래스 멤버
Java 클래스 로더에 의해 메서드 영역에 저장되고 사용
메서드 영역의 클래스와 같은 위치에 고정적으로 위치하고 있는 멤버를 의미 → 객체의 생성 필요 없이 바로 사용 가능
필드와 메서드를 클래스 멤버로 만들기 위해서 static 키워드 사용
- 일반적으로 인스턴스마다 모두 가지고 있을 필요 없는 공용 데이터를 저장하는 필드는 클래스 멤버로 선언하는 게 좋음
- 인스턴스 필드를 사용하지 않고 실행되는 메서드가 존재한다면 static 키워드를 사용하여 클래스 메서드로 선언하는 것이 좋음
※ 주의
- 클래스 멤버로 선언된 메서드는 인스턴스 멤버를 사용할 수 없음
- 반대로 인스턴스 멤버로 선언된 메서드는 클래스 멤버를 사용할 수 있음
- 클래스 멤버는 객체 생성 없이 바로 사용 가능하기 때문에 객체가 생성되어야 존재할 수 있는 인스턴스 멤버를 사용할 수 없음
static String company = "GENESIS"; // 자동차 회사 : GENESIS
String getCompany() {
return "(주)" + company;
}
Car 클래스에서 자동차 회사 이름을 GENESIS 로 고정되어있다고 가정
그럼 모든 Car 클래스의 객체마다 company 인스턴스 필드를 가지고 있을 필요가 없으니 company 를 클래스 멤버로 만들어버려 메모리를 효율적으로 사용 가능
또한 인스턴스 메서드인 getCompany() 는 클래스 멤버인 company 를 사용할 수 있음
static String setCompany(String companyName) {
// System.out.println("자동차 모델 확인: " + model); // 인스턴스 사용 불가
company = companyName;
return company;
}
자동차 회사를 변경할 수 있는 setCompany() 메서드를 클래스 메서드로 만들어서 사용한다고 가정
그럼 인스턴스 필드인 model 을 사용할 수 없음.
클래스 멤버로 지정을 한 이상 범위가 더 광범위해진다.
인스턴스 멤버인 model 의 효력이 벗어나진 것이다.
Car.company = "Audi";
String companyName = Car.setCompany("Benz");
위처럼 클래스 멤버를 사용할 수 있다. 클래스 멤버를 사용하려면 다른 선언 없이 그냥 이름과 함께 도트 연산자를 사용
객체를 생성해서 굳이 할 수는 있지만 추천을 하는 방법은 아님. (가능은 하다는 것)
지역변수
메서드 내부에 선언한 변수
메서드가 실행될 때마다 독립적인 값을 저장하고 관리
메서드 내부에서 정의될 때 생성되고 메서드가 종료될 때 까지만 유지
public class Main {
public static void main(String[] args) {
Main main = new Main();
// 메서드 호출 : main.getClass()
System.out.println("main.getClass() = " + main.getNumber());
System.out.println("main.getClass() = " + main.getNumber());
System.out.println("main.getClass() = " + main.getNumber());
}
public int getNumber() {
int number = 1; // 지역 변수
number += 1;
return number; // 메서드 종료되면 지역변수 제거됨
}
}
// 출력
//main.getNumber() = 2
//main.getNumber() = 2
//main.getNumber() = 2
보다시피 getNumber() 메서드가 실행될 때만 number 가 유지되기 때문에 암만 안에서 더해도 출력하면 계속 2가 나온다.
final 필드와 상수
final 필드
final 필드는 반드시 초기값을 지정해야하고, 해당값을 프로그램이 실행하는 도중에는 절대로 수정할 수 없음
final String company = "GENESIS";
...
Car car = new Car();
System.out.println(car.company);
위처럼 변수를 선언할 때 타입 앞에 final 을 붙여주면 되고 초기화를 하면 됨.
이후에 car.company = "Benz"; 와 같이 수정하면 에러가 뜸.
상수
값이 반드시 한 개 이며 불변의 값을 의미, 따라서 인스턴스마다 상수를 저장할 필요가 없음
static final String COMPANY = "GENESIS";
...
System.out.println(Car.COMPANY);
- final 앞에 static 키위드를 추가하여 모든 인스턴스가 공유할 수 있는 값이 한 개 이며 불변인 상수를 선언할 수 있다.
- 사용방법은 일반적인 클래스 필드와 동일, 수정 불가능
- 일반적으로 상수는 대문자로 작성하는 것이 관례
정리하면 final 을 붙이면 변경 못하게 되고 static 을 붙이면 프로그램 전체에서 쓸 수 있는 변수로 만든다.
'컴퓨터 프로그래밍 > Java' 카테고리의 다른 글
[Java] this와 this(), 접근 제어자, package와 import (0) | 2024.07.29 |
---|---|
[Java] 생성자 (0) | 2024.07.28 |
[Java] 필드와 매서드 (0) | 2024.07.26 |
[Java] 클래스 (설계도) 설계하고 객체 생성 (인스턴스화) (0) | 2024.07.26 |
[Java] Level 1 과제 중 추가로 알게된 점 정리하기 (1) | 2024.07.25 |