[Java] Java 기초 - 자바 코드 구조

Hyunjun Kim·2025년 3월 28일
0

Data_Engineering

목록 보기
12/153

3. 자바의 구조

3.1. 패키지(package)

패키지는 클래스가 위치하는 위계상의 위치를 점(. , dot)으로 구분해서 표시합니다. 이 점(.)은 파일시스템 상에서는 directory로 구분.
패키지는 코드를 만드는 회사나 조직 정보, 제품이나 서비스의 이름, 기능적인 이름 구분을 위계(hieararchy)로 표시함.
관습적으로 회사나 조직 정보.제품이나 서비스의 이름.해당 제품이나 서비스 내에서 기능적이거나 기술적인 구분 순서로 점으로 구분해서 사용한다.

위계상의 위치라는 건 논리적인 것이고 실제 물리적으로는 디렉토리가 되는데 점으로 구분해서 표시한다.

3.2 클래스(class)

자바의 코든 코드는 클래스 파일에 위치해야한다. 사용자가 작성하는 코드는 모두 클래스 블럭 내에 위치해야한다. 클래스 블럭 밖에는 클래스 상단에 위치하는 패키지 이름, import 문, 클래스에 달린 annotation 만 올 수 있다.

자바 파일 이름과 클래스 이름은 같아야 한다.
컴파일하면, 클래스 이름과 동일한 자바 파일 이름으로 .class 파일이 생성된다.
inner class의 경우, $표시가 붙은 뒤에 OuterCLassNamesInnerClassName.cLass 이렇게 파일이 생성됨.

그래서 결국에는 클래스 별로 독립된 class 파일이 존재해야 되는 게 자바의 규칙이고 클래스 이름과 파일의 이름은 동일해야 한다.

3.3 클래스의 이름

결국에는 우리가 클래스 파일을 만들면 누가 읽냐? JVM이 읽는다. 그리고 JVM(Java Virtual Machine)은 클래스로더가 클래스를 메모리에 로딩한다고 앞에서 설명했다.

만약에 같은 이름의 클래스 파일을 로드하면 어떻게 될까?
같은 이름의 파일은 하나밖에 못 만들지 않나요? 그래서 상관없지 않나?

자바 실행할 때,

java -cp

이렇게 여러가지 파라미터를 넣을 수 있는데, java -cp 옵션을 사용하여 여러 개의 class path를 설정하면, 서로 다른 경로에서 동일한 이름의 클래스 파일이 로드될 가능성이 있다.

이 경우 결과는 두 가지다.

  • 되는 경우도 있고, 안 되는 경우도 있다.

클래스 로더는 클래스를 패키지명까지 포함한 "완전한 클래스 이름(Fully Qualified Name)"으로 구분한다.
즉, 패키지명.클래스명 형태로 인식하며, 프로그램 전체에서 유일할 필요는 없고 해당 클래스를 로드하는 클래스 로더 내에서만 유일하면 된다.

동일한 이름의 클래스가 여러 경로에 존재할 때,

  • 같은 패키지, 같은 클래스명: 충돌 가능성이 있음
  • 다른 패키지, 같은 클래스명: 문제없이 로드 가능
  • 다른 클래스 로더에서 로드된 동일한 클래스: 서로 다른 클래스로 취급될 수 있음

이러한 동작 방식으로 인해 ClassNotFoundException, ClassCastException 등의 오류가 발생할 수 있다.
클래스 로더의 동작을 이해하고 올바르게 class path를 설정하는 것이 중요하다.

(클래스로더도 이제 여러 개를 둘 수 있는데 그건 고급 과정이고, 프로그래밍 하면서 쓸 일이 아마 거의 없다고 한다.)


실습 코드

package com.fastcampus.de.java.clip5;

public class OuterClass {
    public static void main(String[] args){
        System.out.println("outer class");
        InnerClass innerClass = new InnerClass();
        innerClass.printName();
    }
    
    public static class InnerClass{
        public void printName(){
            System.out.println(this.getClass().getName());
            System.out.println(this.getClass().getSimpleName());
        }
    }
}

출력 결과
outer class
com.fastcampus.de.java.clip5.OuterClass$InnerClass
InnerClass


실제로 코드로 MyClass.class.getCLassName() 로 조회할 수 있다.
그래서 package 이름을 정할 때, 위계(hieararchy)를 겹치지 않고도 클래스의 목적을 잘 표현하도록 지어야한다.
클래스 선언부에 있는 이름만 조회하려면 Myclass.class.getsimpLeName()
으로 확안할 수 있다.

3.4 클래스패스(Classpath)

우리가 자주 쓰는 system.out.println 요것도 클래스고, 하나의 함수다. 근데 시스템이란 클래스를 만들지 않았었는데 자바 프로그램은 시스템이란 클래스를 어디서 찾았을까?

cd $JAVA_HOME
cd lib
ls -al

JAVA_HOME/lib/ 에 스탠다드 함수 같은 것들이 들어있는데 여기에 있는 .jar 파일들을 기본적으로 classpath에 가지고 있기 때문에 개발 환경에서 자바의 기본함수, 기본 클래스 같은 것들을 사용할 수가 있다.

3.4.1 클래스패스란?

JVM은 자신이 로드할 클래스를 어디서 찾을까? 바로 클래스패스에서 찾는다.
즉, JVM에게 클래스패스가 어디인지 파일시스템의 경로를 알려주어야 클래스를 찾을 수 있다.

3.4.2 클래스패스를 지정하는 방법

main함수가 jar안에 위치해 있고 jar 명령어로 자바 프로그램을 실행시키는 경우(java jar ...) 해당 jar 파일은 기본적으로 Classpath에 포함되어 있다.
환경변수로 지정된 JAVA_HOME 하위의 lib 디렉토리는 지정하지 않아도 클래스패스에 포함됩니다.
java 명령어를 수행하는 현재 디렉토리도 지정하지 않아도 클래스패스에 포함된다.
클래스패스는 환경변수로 지정($CLASSPATH )할 수도 있고, java 파라미터(-cp 또는 -classapth)로 자바 프로그램을 실행시킬 때 전달할 수도 있다.

그리고 여러 개의 디렉토리나 여러 개의 .jar 파일(java archive 파일이라고 해서 java class들이 위치한 압축파일을 말한다.)을 사용하고 여러 가지 라이브러리를 사용한다면 -cp 라는 변수의 파라미터에 아니면 -classpath 라는 변수에다가 구분자로 구분해서 경로를 넣어주면 된다.

내가 여러가지 라이브러리를 사용하고, 제각기 위치한 디렉토리가 다르다면, 모두 CLASSPATH안에 구분자 (Windows: ; 세미콜론, Unix계열: : 콜론)로 구분해서 경로를 넣어줘야 한다.

classpath 실습


  1. external 디렉토리를 만들고 들어가 Callee.java 파일을 만든다.
class Callee {
	public void call(String arg) {
	System.out.println(arg);
	}
}

  1. Callee.java파일을 컴파일
javac Callee.java

  1. external 디렉토리에서 나와서 main 디렉토리를 만들고 그 하위에 Hello.java 파일을 만든다.
class Hello {
	public static void main(String[] args) {
		System.out.println("hello");
		Callee callee = new Callee();
		callee.call("world");
	}
}

  1. Callee 클래스가 위치한 디렉토리를 classpath로 파라미터 세팅을 하고 Hello.java파일을 컴파일.
javac -cp ../external Hello.java

  1. Callee 클래스가 위치한 디렉토리와 현재디렉토리를 classpath로 파라미터 세팅을 하고 Hello.java파일을 컴파일.
  • Linux or Mac (경로 구분을 : 콜론)
java -cp ../external:. Hello
  • Windows (경로 구분을 ; 세미콜론)
java -cp ../external;. Hello

  1. 다음과 같은 결과가 나오면 성공!
    hello
    world
profile
Data Analytics Engineer 가 되

0개의 댓글