[자바 무료 강의] enum - 코드라떼
Lesson List button
코스자바로 배우는 프로그래밍
hamburger button
강의enum최종수정일 2021-09-07
아이콘약 7분

심볼릭 상수를 이용하여 '의미'있는 상수의 값을 사용할 수 있지만, 그보단 Enum을 사용하는 것이 더 좋습니다. 왜 Enum을 사용해야 하는지 알아봅시다.

추가 노트

목차


  1. enum
  2. [추가] Singleton 패턴이란




enum


enum은 자바 가상 머신에 의해 Singleton으로 생성되며 의미 있는 상수를 정의하고 프로그램의 안정성을 위해 사용됩니다.

enum CafeFoodCategory { BREAD, CAKE, COFFEE, BEVERAGE }
copy

enum은 이러한 문제를 해결하기 위해 만들어졌습니다.

public void eat(int foodCategory) { if (0 == foodCategory) { System.out.println("빵"); } else if (1 == foodCategory) { System.out.println("케이크"); } else if (2 == foodCategory) { System.out.println("커피"); } else if (3 == foodCategory) { System.out.println("음료"); } else { System.out.println("존재하지않음"); } }
copy

이러한 메서드가 있다고 가정해봅시다. 해당 메서드는 0~3까지의 정수형 데이터를 넣으면 빵, 케이크, 커피, 음료를 출력하는 메서드입니다.

그리고 이러한 메서드를 사용하려면 일반적으로는 이렇게 할 겁니다.

eat(0); eat(1);
copy

메서드를 사용하는 코드만 본다면 eat(0), eat(1)이 무엇을 의미하는지 알 수 없습니다. 인자로 들어가는 0과 1의 의미를 확인하려면 eat 메서드 구현체를 직접 확인해야겠지요.

그래서 이러한 불편함과 문제를 해결하기 위해 정수를 심볼릭 상수로 만들어서 의미를 부여했습니다.

final class FoodCategory { public static final int BREAD = 0; public static final int CAKE = 1; public static final int COFFEE = 2; public static final int BEVERAGE = 3; }
copy

심볼릭 상수를 정의한 FoodCategory 클래스를 만든다면 좀 더 낫습니다. 어느 정도 코드의 의미를 파악할 수 있지요.

eat(FoodCategory.BREAD); eat(FoodCategory.CAKE);
copy

그러나 해당 코드에는 본질적인 문제가 있습니다. eat 메서드는 정수로 된 모든 인자를 전달받을 수 있기 때문에 이러한 코드 작성도 가능합니다.

eat(-1); eat(-100);
copy

eat 메서드를 구현한 개발자는 eat 메서드를 이렇게 사용하라고 만들지는 않았을 겁니다. 그러나 논리적으로는 발생할 수 있는 일입니다. 정수형 인자를 전달받기 전에 특정 정수만 전달할 수 있도록 할 수 없으니까요.

이럴 땐 enum을 이용하면 상수에 의미를 부여하면서 전달할 수 있는 인자를 제한할 수 있습니다.



FoodCategory를 정의한 enum

enum FoodCategory { BREAD, CAKE, COFFEE, BEVERAGE }
copy



enum 상수를 전달 받는 eat 메서드

public void eat(FoodCategory foodCategory) { if (FoodCategory.BREAD == foodCategory) { System.out.println("빵"); } else if (FoodCategory.CAKE == foodCategory) { System.out.println("케이크"); } else if (FoodCategory.COFFEE == foodCategory) { System.out.println("커피"); } else if (FoodCategory.BAVERAGE == foodCategory) { System.out.println("음료"); } }
copy

eat 메서드를 FoodCategory enum에 정의된 상수만 전달받을 수 있도록 변경합니다.

eat(FoodCategory.BREAD); eat(FoodCategory.CAKE);
copy

그러면 eat 메서드를 호출할 때 enum에 정의된 상수만 전달할 수 있습니다. 코드의 가독성도 좋아지고 코드의 안정성도 확보됩니다.


ordinal()

ordinal() 메서드는 enum 상수에 정의된 순서값을 반환합니다.

enum FoodCategory { BREAD, CAKE, COFFEE, BEVERAGE }
copy
System.out.println(FoodCategory.CAKE.ordinal()); // 출력 : 1
copy

단순히 순서값만 반환하기 때문에 정의된 상수의 위치가 달라지면 순서값이 달라질 수 있습니다. 특별한 상황이 아니라면 ordinal()에 반환된 값을 이용하여 조건을 판단하는 것을 하지 않는 것이 좋습니다.


name()

name() 메서드는 enum 상수에 정의된 이름을 반환합니다.

enum FoodCategory { BREAD, CAKE, COFFEE, BEVERAGE }
copy
System.out.println(FoodCategory.CAKE.name()); // 출력 : CAKE
copy

만약에 상수의 이름을 이렇게 작성했다면 다음과 같이 출력됩니다.

enum FoodCategory { Bread, Cake, Coffee, Beverage }
copy
System.out.println(FoodCategory.Cake.name()); // 출력 : Cake
copy


Enum을 다르게 정의하기

enum 상수에 특정한 값을 정의할 수 있습니다.

enum FoodCategory { BREAD(2800), CAKE(17000), COFFEE(4300), BEVERAGE(2500); int cost; FoodCategory(int cost) { this.cost = cost; } }
copy

상수에 특정한 값을 지정할 때는 상수의 끝맺음에 반드시 세미콜론(;)을 작성해 주어야 합니다. 그리고 특정한 값의 정의에 맞게 생성자를 반드시 정의해 주어야 합니다. 그리고 enum 내에 변수를 선언하고 생성자를 통해 값을 저장하면 다음과 같이 사용할 수 있습니다.

System.out.println(FoodCategory.BREAD.cost); System.out.println(FoodCategory.CAKE.cost); System.out.println(FoodCategory.COFFEE.cost); System.out.println(FoodCategory.BEVERAGE.cost); // 출력 2800 17000 4300 2500
copy



하나의 특정한 값이 아니라 여러 개의 특정한 값을 지정할 수 있습니다.

enum FoodCategory { BREAD("빵", 2800), CAKE("케이크", 17000), COFFEE("커피", 4300), BEVERAGE("음료", 2500); int name; int cost; FoodCategory(String name, int cost) { this.name = name; this.cost = cost; } }
copy
System.out.println(FoodCategory.CAKE.name); System.out.println(FoodCategory.CAKE.cost); // 출력 케이크 17000
copy


Enum의 생성자는 기본적으로 private이다

enum의 특성상 내부적으로 singleton 방식으로 관리하기 때문에 enum의 생성자는 기본적으로 private로 처리됩니다.

// 불가능한 코드 FoodCategory foodCategory = new FoodCategory(…);
copy




[추가] Singleton 패턴이란


Singleton Pattern은 인스턴스 생성 패턴 중 하나로 인스턴스를 한 번 생성하고 인스턴스의 내용을 여러 메서드에서 공유하여 사용할 수 있는 패턴입니다.

public class Configuration { private static Configuration configuration; private Configuration() { } public static Configuration getInstance() { if (null == configuration) { configuration = new Configuration(); } return configuration; } }
copy

Singleton Patternnew 키워드로 인스턴스를 생성하지 못하게 함과 동시에 인스턴스를 생성할 수 있는 특정 정적 메서드를 통해서만 인스턴스를 생성하도록 하고 생성된 인스턴스는 정적 변수에 저장하여 인스턴스에 접근할 수 있도록 합니다.

인스턴스를 생성하는 방법은 Configuration.getInstance() 를 통해서만 생성할 수 있으며 configuration 정적 변수null일 경우 생성자를 통해 인스턴스를 생성합니다.

Configuration configuration1 = Configuration.getInstance(); System.out.println(configuration1); // 동일한 해시코드 Configuration@610455d6 Configuration configuration2 = Configuration.getInstance(); System.out.println(configuration2); // 동일한 해시코드 Configuration@610455d6
copy

여러번의 Configuration.getInstance() 호출에도 동일한 인스턴스의 참조 값을 반환하기 때문에 인스턴스를 생성함에 따른 메모리 공간을 절약할 수 있습니다.





Singleton 클래스

public class Configuration { private static Configuration configuration; private String cafeName = "카페"; private String cafeAddress = "저 먼나라 주소"; private Configuration() { } public static Configuration getInstance() { if (null == configuration) { configuration = new Configuration(); } return configuration; } public String getCafeName() { return cafeName; } public String getCafeAddress() { return cafeAddress; } }
copy
Configuration configuration1 = Configuration.getInstance(); System.out.println(configuration.getCafeName()); // 출력 "카페" System.out.println(configuration.getCafeAddress()); // 출력 "저 먼나라 주소"
copy

인스턴스 변수를 선언하여 사용하거나 메서드를 정의하여 일반적인 클래스처럼 사용할 수 있습니다.

그렇다면 이런 의문이 들 수도 있습니다.

인스턴스를 한 번 생성하고 값을 공유한다면 굳이 Singleton Pattern의 인스턴스가 아니라 정적 변수와 정적 메서드로 만들어도 되지 않나요? 라고 생각하셨으면 공부 잘 하신겁니다.





Singleton아닌 클래스

public class Configuration { private static String cafeName = "카페"; private static String cafeAddress = "저 먼나라 주소"; public static String getCafeName() { return cafeName; } public static String getCafeAddress() { return cafeAddress; } }
copy
System.out.println(Configuration.getCafeName()); // 출력 "카페" System.out.println(Configuration.getCafeAddress()); // 출력 "저 먼나라 주소"
copy

결과만 놓고 보면 Singleton Pattern으로 만들어진 인스턴스와 정적 변수, 정적 메서드와 큰 차이가 없어보입니다.

다만 차이점은 인스턴스 지연 생성(Lazy Load) 입니다.

“자바 메모리 구조 - 기초” 강의에서 정적 변수와 정적 메서드는 Method Area에 저장되며 프로그램 시작 시 메모리에 할당되고 적재된다고 했었습니다. 그 말은 해당 정적 변수나 정적 메서드를 프로그램에서 사용하지 않는다 하더라도 메모리 공간을 차지하게 됩니다.

그러나 Singleton Pattern은 호출 하지 않는다면 최소 인스턴스의 참조 값을 저장하는 configuration 정적 변수와 인스턴스를 생성하기 위한 Configuration.getInstance() 정적 메서드만 메모리에 할당됩니다.

진짜 필요할 때 Configuration.getInstance() 를 호출 하여 최초 메모리에 할당하는 지연 생성(Lazy Load) 이라는 차이점이 있습니다.

또한 이렇게 까지는 하지 않지만 configuration 정적 변수에 저장된 인스턴스의 참조 값을 null로 바꾸어 Heap 메모리에 저장된 Configuration 인스턴스를 Garbage Collector가 수집할 수 있도록 할 수 있습니다.





Singleton 인스턴스 해제

public class Configuration { private static Configuration configuration; … public void free() { configuration = null; } … }
copy
Configuration configuration = Configuration.getInstance(); … configuration.free();
copy

Singleton Pattern 클래스로 좀 더 유동적으로 메모리를 사용할 수 있기 때문에 정적 변수와 정적 메서드와는 차이가 있습니다.

도전자 질문
아이콘ggujunhee(2021-10-13 08:40 작성됨)
5:07에   gender 생성자 부분에 this.value = value; 가 되어야하는 거 아닌가요??? this.value = sex;면 sex는 어디서 받아오는 건가요....??
아이콘코드라떼(2021-10-13 10:33 작성됨)
안녕하세요. 코드라떼입니다 :)

먼저 불편함을 드려 죄송합니다.

영상 확인 결과 잘못 작성된 내용을 확인했습니다.
this.value = value;가 맞습니다.

감사합니다.
아이콘자바배움이(2021-07-08 13:43 작성됨)
추가노트에

Configuration configuration1 = Configuration.getInstance();
System.out.println(configuration2);
// 동일한 해시코드 Configuration@610455d6

configuration2인데 1이라고 되어있어요. ㅎㅎ
아이콘코드라떼(2021-07-08 16:29 작성됨)
자바배움이님 감사합니다^^ 수정했습니다.

아이콘resCogitans(2021-07-01 02:33 작성됨)
1:20 정도에 정적상수변수 클래스명이 CafeFoodCategory로 나온 오타가 있는 것 같습니다
아이콘코드라떼(2021-07-01 04:56 작성됨)
부끄럽네요..

확인했습니다^^ 감사합니다!!
이용약관|개인정보취급방침
알유티씨클래스|대표, 개인정보보호책임자 : 이병록
이메일 : cs@codelatte.io
사업자등록번호 : 824-06-01921
통신판매업신고 : 2021-성남분당C-0740
주소 : 경기도 성남시 분당구 대왕판교로645번길 12, 9층 24호
파일
파일파일
Root
파일

실습코드를 살펴봅시다.

Output
root$
Lesson List button
코스자바로 배우는 프로그래밍
hamburger button
강의enum최종수정일 2021-09-07
아이콘약 7분

심볼릭 상수를 이용하여 '의미'있는 상수의 값을 사용할 수 있지만, 그보단 Enum을 사용하는 것이 더 좋습니다. 왜 Enum을 사용해야 하는지 알아봅시다.

추가 노트

목차


  1. enum
  2. [추가] Singleton 패턴이란




enum


enum은 자바 가상 머신에 의해 Singleton으로 생성되며 의미 있는 상수를 정의하고 프로그램의 안정성을 위해 사용됩니다.

enum CafeFoodCategory { BREAD, CAKE, COFFEE, BEVERAGE }
copy

enum은 이러한 문제를 해결하기 위해 만들어졌습니다.

public void eat(int foodCategory) { if (0 == foodCategory) { System.out.println("빵"); } else if (1 == foodCategory) { System.out.println("케이크"); } else if (2 == foodCategory) { System.out.println("커피"); } else if (3 == foodCategory) { System.out.println("음료"); } else { System.out.println("존재하지않음"); } }
copy

이러한 메서드가 있다고 가정해봅시다. 해당 메서드는 0~3까지의 정수형 데이터를 넣으면 빵, 케이크, 커피, 음료를 출력하는 메서드입니다.

그리고 이러한 메서드를 사용하려면 일반적으로는 이렇게 할 겁니다.

eat(0); eat(1);
copy

메서드를 사용하는 코드만 본다면 eat(0), eat(1)이 무엇을 의미하는지 알 수 없습니다. 인자로 들어가는 0과 1의 의미를 확인하려면 eat 메서드 구현체를 직접 확인해야겠지요.

그래서 이러한 불편함과 문제를 해결하기 위해 정수를 심볼릭 상수로 만들어서 의미를 부여했습니다.

final class FoodCategory { public static final int BREAD = 0; public static final int CAKE = 1; public static final int COFFEE = 2; public static final int BEVERAGE = 3; }
copy

심볼릭 상수를 정의한 FoodCategory 클래스를 만든다면 좀 더 낫습니다. 어느 정도 코드의 의미를 파악할 수 있지요.

eat(FoodCategory.BREAD); eat(FoodCategory.CAKE);
copy

그러나 해당 코드에는 본질적인 문제가 있습니다. eat 메서드는 정수로 된 모든 인자를 전달받을 수 있기 때문에 이러한 코드 작성도 가능합니다.

eat(-1); eat(-100);
copy

eat 메서드를 구현한 개발자는 eat 메서드를 이렇게 사용하라고 만들지는 않았을 겁니다. 그러나 논리적으로는 발생할 수 있는 일입니다. 정수형 인자를 전달받기 전에 특정 정수만 전달할 수 있도록 할 수 없으니까요.

이럴 땐 enum을 이용하면 상수에 의미를 부여하면서 전달할 수 있는 인자를 제한할 수 있습니다.



FoodCategory를 정의한 enum

enum FoodCategory { BREAD, CAKE, COFFEE, BEVERAGE }
copy



enum 상수를 전달 받는 eat 메서드

public void eat(FoodCategory foodCategory) { if (FoodCategory.BREAD == foodCategory) { System.out.println("빵"); } else if (FoodCategory.CAKE == foodCategory) { System.out.println("케이크"); } else if (FoodCategory.COFFEE == foodCategory) { System.out.println("커피"); } else if (FoodCategory.BAVERAGE == foodCategory) { System.out.println("음료"); } }
copy

eat 메서드를 FoodCategory enum에 정의된 상수만 전달받을 수 있도록 변경합니다.

eat(FoodCategory.BREAD); eat(FoodCategory.CAKE);
copy

그러면 eat 메서드를 호출할 때 enum에 정의된 상수만 전달할 수 있습니다. 코드의 가독성도 좋아지고 코드의 안정성도 확보됩니다.


ordinal()

ordinal() 메서드는 enum 상수에 정의된 순서값을 반환합니다.

enum FoodCategory { BREAD, CAKE, COFFEE, BEVERAGE }
copy
System.out.println(FoodCategory.CAKE.ordinal()); // 출력 : 1
copy

단순히 순서값만 반환하기 때문에 정의된 상수의 위치가 달라지면 순서값이 달라질 수 있습니다. 특별한 상황이 아니라면 ordinal()에 반환된 값을 이용하여 조건을 판단하는 것을 하지 않는 것이 좋습니다.


name()

name() 메서드는 enum 상수에 정의된 이름을 반환합니다.

enum FoodCategory { BREAD, CAKE, COFFEE, BEVERAGE }
copy
System.out.println(FoodCategory.CAKE.name()); // 출력 : CAKE
copy

만약에 상수의 이름을 이렇게 작성했다면 다음과 같이 출력됩니다.

enum FoodCategory { Bread, Cake, Coffee, Beverage }
copy
System.out.println(FoodCategory.Cake.name()); // 출력 : Cake
copy


Enum을 다르게 정의하기

enum 상수에 특정한 값을 정의할 수 있습니다.

enum FoodCategory { BREAD(2800), CAKE(17000), COFFEE(4300), BEVERAGE(2500); int cost; FoodCategory(int cost) { this.cost = cost; } }
copy

상수에 특정한 값을 지정할 때는 상수의 끝맺음에 반드시 세미콜론(;)을 작성해 주어야 합니다. 그리고 특정한 값의 정의에 맞게 생성자를 반드시 정의해 주어야 합니다. 그리고 enum 내에 변수를 선언하고 생성자를 통해 값을 저장하면 다음과 같이 사용할 수 있습니다.

System.out.println(FoodCategory.BREAD.cost); System.out.println(FoodCategory.CAKE.cost); System.out.println(FoodCategory.COFFEE.cost); System.out.println(FoodCategory.BEVERAGE.cost); // 출력 2800 17000 4300 2500
copy



하나의 특정한 값이 아니라 여러 개의 특정한 값을 지정할 수 있습니다.

enum FoodCategory { BREAD("빵", 2800), CAKE("케이크", 17000), COFFEE("커피", 4300), BEVERAGE("음료", 2500); int name; int cost; FoodCategory(String name, int cost) { this.name = name; this.cost = cost; } }
copy
System.out.println(FoodCategory.CAKE.name); System.out.println(FoodCategory.CAKE.cost); // 출력 케이크 17000
copy


Enum의 생성자는 기본적으로 private이다

enum의 특성상 내부적으로 singleton 방식으로 관리하기 때문에 enum의 생성자는 기본적으로 private로 처리됩니다.

// 불가능한 코드 FoodCategory foodCategory = new FoodCategory(…);
copy




[추가] Singleton 패턴이란


Singleton Pattern은 인스턴스 생성 패턴 중 하나로 인스턴스를 한 번 생성하고 인스턴스의 내용을 여러 메서드에서 공유하여 사용할 수 있는 패턴입니다.

public class Configuration { private static Configuration configuration; private Configuration() { } public static Configuration getInstance() { if (null == configuration) { configuration = new Configuration(); } return configuration; } }
copy

Singleton Patternnew 키워드로 인스턴스를 생성하지 못하게 함과 동시에 인스턴스를 생성할 수 있는 특정 정적 메서드를 통해서만 인스턴스를 생성하도록 하고 생성된 인스턴스는 정적 변수에 저장하여 인스턴스에 접근할 수 있도록 합니다.

인스턴스를 생성하는 방법은 Configuration.getInstance() 를 통해서만 생성할 수 있으며 configuration 정적 변수null일 경우 생성자를 통해 인스턴스를 생성합니다.

Configuration configuration1 = Configuration.getInstance(); System.out.println(configuration1); // 동일한 해시코드 Configuration@610455d6 Configuration configuration2 = Configuration.getInstance(); System.out.println(configuration2); // 동일한 해시코드 Configuration@610455d6
copy

여러번의 Configuration.getInstance() 호출에도 동일한 인스턴스의 참조 값을 반환하기 때문에 인스턴스를 생성함에 따른 메모리 공간을 절약할 수 있습니다.





Singleton 클래스

public class Configuration { private static Configuration configuration; private String cafeName = "카페"; private String cafeAddress = "저 먼나라 주소"; private Configuration() { } public static Configuration getInstance() { if (null == configuration) { configuration = new Configuration(); } return configuration; } public String getCafeName() { return cafeName; } public String getCafeAddress() { return cafeAddress; } }
copy
Configuration configuration1 = Configuration.getInstance(); System.out.println(configuration.getCafeName()); // 출력 "카페" System.out.println(configuration.getCafeAddress()); // 출력 "저 먼나라 주소"
copy

인스턴스 변수를 선언하여 사용하거나 메서드를 정의하여 일반적인 클래스처럼 사용할 수 있습니다.

그렇다면 이런 의문이 들 수도 있습니다.

인스턴스를 한 번 생성하고 값을 공유한다면 굳이 Singleton Pattern의 인스턴스가 아니라 정적 변수와 정적 메서드로 만들어도 되지 않나요? 라고 생각하셨으면 공부 잘 하신겁니다.





Singleton아닌 클래스

public class Configuration { private static String cafeName = "카페"; private static String cafeAddress = "저 먼나라 주소"; public static String getCafeName() { return cafeName; } public static String getCafeAddress() { return cafeAddress; } }
copy
System.out.println(Configuration.getCafeName()); // 출력 "카페" System.out.println(Configuration.getCafeAddress()); // 출력 "저 먼나라 주소"
copy

결과만 놓고 보면 Singleton Pattern으로 만들어진 인스턴스와 정적 변수, 정적 메서드와 큰 차이가 없어보입니다.

다만 차이점은 인스턴스 지연 생성(Lazy Load) 입니다.

“자바 메모리 구조 - 기초” 강의에서 정적 변수와 정적 메서드는 Method Area에 저장되며 프로그램 시작 시 메모리에 할당되고 적재된다고 했었습니다. 그 말은 해당 정적 변수나 정적 메서드를 프로그램에서 사용하지 않는다 하더라도 메모리 공간을 차지하게 됩니다.

그러나 Singleton Pattern은 호출 하지 않는다면 최소 인스턴스의 참조 값을 저장하는 configuration 정적 변수와 인스턴스를 생성하기 위한 Configuration.getInstance() 정적 메서드만 메모리에 할당됩니다.

진짜 필요할 때 Configuration.getInstance() 를 호출 하여 최초 메모리에 할당하는 지연 생성(Lazy Load) 이라는 차이점이 있습니다.

또한 이렇게 까지는 하지 않지만 configuration 정적 변수에 저장된 인스턴스의 참조 값을 null로 바꾸어 Heap 메모리에 저장된 Configuration 인스턴스를 Garbage Collector가 수집할 수 있도록 할 수 있습니다.





Singleton 인스턴스 해제

public class Configuration { private static Configuration configuration; … public void free() { configuration = null; } … }
copy
Configuration configuration = Configuration.getInstance(); … configuration.free();
copy

Singleton Pattern 클래스로 좀 더 유동적으로 메모리를 사용할 수 있기 때문에 정적 변수와 정적 메서드와는 차이가 있습니다.

도전자 질문
아이콘ggujunhee(2021-10-13 08:40 작성됨)
5:07에   gender 생성자 부분에 this.value = value; 가 되어야하는 거 아닌가요??? this.value = sex;면 sex는 어디서 받아오는 건가요....??
아이콘코드라떼(2021-10-13 10:33 작성됨)
안녕하세요. 코드라떼입니다 :)

먼저 불편함을 드려 죄송합니다.

영상 확인 결과 잘못 작성된 내용을 확인했습니다.
this.value = value;가 맞습니다.

감사합니다.
아이콘자바배움이(2021-07-08 13:43 작성됨)
추가노트에

Configuration configuration1 = Configuration.getInstance();
System.out.println(configuration2);
// 동일한 해시코드 Configuration@610455d6

configuration2인데 1이라고 되어있어요. ㅎㅎ
아이콘코드라떼(2021-07-08 16:29 작성됨)
자바배움이님 감사합니다^^ 수정했습니다.

아이콘resCogitans(2021-07-01 02:33 작성됨)
1:20 정도에 정적상수변수 클래스명이 CafeFoodCategory로 나온 오타가 있는 것 같습니다
아이콘코드라떼(2021-07-01 04:56 작성됨)
부끄럽네요..

확인했습니다^^ 감사합니다!!
이용약관|개인정보취급방침
알유티씨클래스|대표, 개인정보보호책임자 : 이병록
이메일 : cs@codelatte.io|운영시간 09:00 - 18:00(평일)
사업자등록번호 : 824-06-01921|통신판매업신고 : 2021-성남분당C-0740
주소 : 경기도 성남시 분당구 대왕판교로645번길 12, 9층 24호(경기창조혁신센터)
파일
파일파일
Root
파일

실습코드를 살펴봅시다.

Output
root$