좋은 질문이에요. 이 코드는 한눈에 봐도 거의 맞는 것처럼 보이지만, 컴파일 오류가 발생하는 치명적인 문제점이 있습니다.
아래에서 전체적으로 어느 부분이 잘못됐고, 왜 잘못됐는지 한 줄 한 줄 디버깅하듯이 설명드릴게요.
class Person {
private String name;
public Person(String val) {
name = val;
}
public static String get() {
return name; // ❌ 문제 발생
}
public void print() {
System.out.println(name);
}
}
public class main {
public static void main(String[] args) {
Person obj = new Person("Kim");
obj.print();
}
}
public static String get() {
return name;
}
여기서 컴파일 오류가 발생합니다.
name은 인스턴스 변수 (non-static)private String name;
이 변수는 객체가 생성될 때마다 개별적으로 존재하는 변수입니다. 즉, obj1, obj2 각각의 name이 따로 있음.
get() 메서드는 정적 메서드 (static)public static String get()
static 메서드는 클래스 차원에서 동작하므로, 객체 없이도 Person.get() 식으로 호출됩니다.
즉, static 메서드는 클래스 자체만 보고 실행되기 때문에, 인스턴스 변수인 name을 직접 사용할 수 없습니다.
✅ 정리
static메서드 안에서는name같은 인스턴스 변수 사용 불가
그래서return name;코드는 컴파일 에러 발생:
❗ "non-static variable name cannot be referenced from a static context"
get()을 static → 인스턴스 메서드로 바꾸기public String get() {
return name;
}
name을 static 변수로 바꾸기 (그러나 일반적인 상황에서는 지양)private static String name;
class Person {
private String name;
public Person(String val) {
name = val;
}
// static 제거함
public String get() {
return name;
}
public void print() {
System.out.println(name);
}
}
public class Main {
public static void main(String[] args) {
Person obj = new Person("Kim");
obj.print(); // Kim 출력
System.out.println(obj.get()); // Kim 출력
}
}
좋아요! 지금부터 Java에서 static과 인스턴스 변수/메서드의 관계를 아주 기초부터 자세하게, 예제와 함께 시각적으로 설명해드릴게요.
완전 초보자 기준으로 하나도 안 빼고 순서대로 설명합니다.
| 구분 | static | 인스턴스 (non-static) |
|---|---|---|
| 소속 | 클래스(Class) | 객체(Instance) |
| 메모리 | 프로그램 시작 시 1개 생성 | 객체를 만들 때마다 새로 생성 |
| 사용 | 클래스명으로 접근 | 객체명으로 접근 |
| 예시 | Person.count | obj.name |
class Person {
String name; // 인스턴스 변수
static int count = 0; // 클래스 변수 (static)
public Person(String name) {
this.name = name;
count++; // 객체가 생성될 때마다 count 증가
}
public void printName() { // 인스턴스 메서드
System.out.println("이름: " + name);
}
public static void printCount() { // static 메서드
System.out.println("전체 인원 수: " + count);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Kim");
Person p2 = new Person("Lee");
p1.printName(); // 이름: Kim
p2.printName(); // 이름: Lee
Person.printCount(); // 전체 인원 수: 2 ✅ (클래스명으로 호출)
}
}
🧠 JVM 메모리:
---------------------
| static 영역 |
| - Person.count = 2 | <-- 클래스 변수 (딱 1개)
---------------------
| 힙(heap) 영역 |
| - p1.name = "Kim" |
| - p2.name = "Lee" | <-- 각각 객체마다 name이 따로 존재
---------------------
<public static void printCount() {
System.out.println("이름은 " + name); // ❌ 오류: static 메서드에서 name 접근 불가
}
이유:
printCount()는 클래스 차원에서 호출됨 (Person.printCount())name은 객체가 있어야만 존재하는 값public void printInfo() {
System.out.println("이름: " + name); // 가능: this.name
System.out.println("전체 인원: " + count); // 가능: static 변수도 접근 가능
}
왜 가능하냐면?
| 메서드 | 호출 방식 | 내부에서 접근 가능한 것 |
|---|---|---|
| static | Person.method() | static 변수/메서드만 |
| 인스턴스 | obj.method() | 인스턴스 + static 모두 가능 |
static은 "클래스 전체에 하나뿐인 공유 자원"static 메서드에서는 인스턴스 변수/메서드에 접근 ❌class Person {
String name;
public static void printName() {
System.out.println(name); // 오류 발생!
}
}
방법 1: static 제거
public void printName() {
System.out.println(name); // 정상 작동
}
방법 2: name도 static으로 변경
static String name;
public static void printName() {
System.out.println(name); // 가능하지만 모든 사람이 같은 이름 가짐
}