1. 클래스 선언 시 오류
접근 제한자를 생략함 (package-private가 기본)
Java에서 클래스에 접근 제한자를 명시하지 않으면 현재 패키지 내부에서만 접근할 수 있습니다. 이를 package-private 또는 '기본 접근'이라고 합니다. 예:
// 파일 Book.java
class Book {
String title;
}
이런 클래스는 다른 패키지에서 사용할 수 없습니다. 클래스가 어디서든 접근 가능하도록 하려면(대부분의 핵심 모델은 그렇습니다) public 제한자를 사용하세요:
public class Book {
String title;
}
왜 중요할까요?
public을 빼먹으면, 나중에 다른 패키지의 Library가 왜 당신의 클래스를 보지 못하는지 한참 헤매게 됩니다.
클래스 이름과 파일 이름 불일치
Java에서는 클래스가 들어 있는 파일 이름이 해당 파일의 public 클래스 이름과 동일해야 합니다(대소문자 구분!). 예:
// 파일 Book.java
public class Book {
// ...
}
파일을 book.java(소문자)나, 더 나쁘게는 BooK.java로 저장하면 컴파일 오류가 발생합니다. 이는 IDE가 클래스를 이름만 바꾸고 파일 이름을 바꾸지 않았을 때 강하게 경고하는 이유 중 하나입니다.
선언 구문 오류: 중괄호 누락, 메서드와 필드의 잘못된 위치
Java는 엄격한 언어입니다. 어딘가에서 중괄호를 빼먹거나 실수로 메서드 안에 다른 메서드를 선언하면(이건 허용되지 않습니다!) 컴파일러가 즉시 오류를 알려줍니다.
잘못된 선언 예:
public class User
String name; // 앗! 클래스의 중괄호가 빠졌습니다.
public void printName() {
System.out.println(name);
}
}
올바른 예:
public class User {
String name;
public void printName() {
System.out.println(name);
}
}
기억하세요:
- 모든 필드와 메서드는 클래스의 중괄호 안에서만 선언합니다.
- 메서드는 서로 중첩될 수 없습니다(다른 언어에서는 허용되기도 하지만 Java에서는 안 됩니다!).
2. 객체 생성 시 오류
초기화 전에 객체를 사용하려는 시도 (NullPointerException)
가장 흔한 오류는 아직 생성되지 않은 객체에 접근하는 것입니다. Java에서 참조형 변수의 기본값은 null입니다.
예:
User user;
System.out.println(user.name); // NullPointerException!
왜 그럴까요?
변수 user는 선언만 되었고 초기화되지 않았습니다. 필드나 메서드에 접근하려 하면 NPE(NullPointerException)가 발생합니다.
올바른 방식:
User user = new User();
System.out.println(user.name); // 이제 괜찮습니다(필드가 null이 아니라면)
생성자 호출 오류(매개변수 불일치, 기본 생성자 없음)
클래스에 매개변수가 있는 생성자만 있는 경우, 매개변수 없이 객체를 생성하려고 하면 컴파일 오류가 납니다.
public class Book {
String title;
public Book(String title) {
this.title = title;
}
}
Book book = new Book(); // 오류! 매개변수 없는 생성자가 없습니다.
해결: 매개변수 없는 생성자를 추가하거나, 늘 필요한 값을 전달하세요:
Book book = new Book("자바 입문서");
재사용 대신 객체를 여러 번 생성함
가끔 초보자는 이미 만든 객체를 재사용하지 않고, 접근할 때마다 새로 생성하곤 합니다.
Book book = new Book("자바 입문서");
System.out.println(book.title);
book = new Book("자바 입문서"); // 왜 또 생성하나요? 이미 같은 객체가 있었습니다!
System.out.println(book.title);
이것은 컴파일 오류는 아니지만, 안 좋은 스타일의 신호입니다 — 기존 객체에 대한 참조를 잃고 불필요한 메모리를 사용하게 됩니다.
3. 베스트 프랙티스: 같은 실수를 피하는 법
항상 접근 제한자를 명시하세요
public, private, protected를 아끼지 말고 적어주세요 — 보안뿐 아니라 코드 가독성에 중요합니다. IDE가 물론 힌트를 주지만, 처음부터 습관을 들이는 편이 좋습니다.
예:
public class User {
private String name;
// ...
}
클래스 명명 규칙을 지키세요
- 클래스 이름은 대문자로 시작하고 CamelCase를 사용합니다: Book, LibraryUser, BookManager.
- 파일 이름은 클래스 이름과 정확히 같아야 합니다.
필수 필드 초기화에는 생성자를 사용하세요
객체에 생성 시 반드시 채워야 하는 필드가 있다면, 매개변수가 있는 생성자를 추가하세요. 사용 단계에서의 오류를 방지할 수 있습니다.
예:
public class User {
private String name;
public User(String name) {
this.name = name;
}
}
이제 이름 없이 User를 생성할 수 없습니다 — 컴파일러가 허용하지 않습니다.
4. 지식 적용: 미니‑애플리케이션 "라이브러리" 만들기
우리의 학습용 애플리케이션을 계속 확장해 봅시다. Book 클래스와 책들을 관리하는 Library 클래스가 있다고 가정합시다.
올바른 클래스 선언 예
// 파일 Book.java
public class Book {
private String title;
private String author;
// 매개변수가 있는 생성자
public Book(String title, String author) {
this.title = title;
this.author = author;
}
// 게터
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
}
올바른 객체 생성 예
Book book = new Book("자바 입문서", "John Doe");
System.out.println(book.getTitle() + " - " + book.getAuthor());
매니저 클래스 예
// 파일 Library.java
import java.util.ArrayList;
public class Library {
private ArrayList<Book> books = new ArrayList<>();
public void addBook(Book book) {
books.add(book);
}
public void printAllBooks() {
for (Book book : books) {
System.out.println(book.getTitle() + " - " + book.getAuthor());
}
}
}
main에서의 사용
public class Main {
public static void main(String[] args) {
Library library = new Library();
Book book1 = new Book("자바 입문서", "John Doe");
Book book2 = new Book("쉽게 배우는 OOP", "Ivan Ivanov");
library.addBook(book1);
library.addBook(book2);
library.printAllBooks();
}
}
5. 그림과 도식
도식: 무엇을 어디에 선언하나요?
+-----------------------------+
| Book.java |
|-----------------------------|
| public class Book { |
| private String title; | <--- 필드(클래스 내부에서만)
| ... |
| public Book(...) {...} | <--- 생성자(클래스 내부)
| public String getTitle()| <--- 메서드(클래스 내부)
| } |
+-----------------------------+
+-----------------------------+
| Main.java |
|-----------------------------|
| public class Main { |
| public static void main |
| // 객체 생성 |
| Book book = new Book|
| } |
+-----------------------------+
6. 흔한 오류 살펴보기
오류 1: 클래스 이름과 파일 이름 불일치
// 파일: Libraryuser.java
public class LibraryUser { // 클래스 이름은 대문자 U, 파일은 소문자!
// ...
}
class LibraryUser is public, should be declared in a file named LibraryUser.java
오류 2: 초기화되지 않은 객체 사용 시도
Book book;
System.out.println(book.getTitle()); // NullPointerException!
오류 3: 중괄호를 잊음
public class Book
private String title; // 캡슐화를 위해 필드는 보통 private로 만듭니다
// ...
}
';' expected
오류 4: 메서드 안에 메서드 선언
public class User {
public void printName() {
void sayHello() {
System.out.println("Hello!"); // 메서드 안에 메서드를 선언할 수 없습니다!
}
}
}
illegal start of type
GO TO FULL VERSION