: 상수를 대체하기 위해 나온 문법으로, 상수로 사용할 값을 미리 선언하여 사용할때 쓰는 데이터 타입이다.
데이터값을 정해 줄 경우에는 생성자를 만들어서 괄호속의 값이 변수에 저장되도록 해야한다.
선언 방법
enum 열거형이름 {상수값1, 상수값2, 상수값3, ..., 상수값n};
주요 사용 메소드
사용법
뜻
name()
열거형 상수객체의 이름을 문자열로 반환한다.
ordinal()
열거형 상수가 정의된 순서값을 반환한다. (기본적으로 0부터 시작함)
valueOf("열거형상수이름")
지정된 열거형에서 '열거형상수이름'과 일치하는 열거형 상수객체를 반환한다.
ex)
enum 사용 전
장미가 아닌데도 장미로 출력되는 문제가 존재함
package kr.or.ddit.basic;
class Flower {
static final int ROSE = 1;
static final int TULIP = 2;
}
class Animal {
static final int LION = 1;
static final int TIGER = 2;
}
public class T07EnumTest {
public static void main(String[] args) {
int a = Animal.LION;
if(a == Flower.ROSE) {
System.out.println("이것은 장미가 확실합니다.");
}
}
}
결과 화면1
enum 사용
package kr.or.ddit.basic;
/*
* 열거형 => 상수값들을 선언하는 방법
*
* static final int A = 0;
* static final int B = 1;
* static final int C = 2;
* static final int D = 3;
*
* enum Data {A, B, C, D};
*
* 열거형 선언하는 방법
* enum 열거형이름 {상수값1, 상수값2, 상수값3, ..., 상수값n};
*
*/
public class T07EnumTest {
// City 열거형 객체 선언(기본값을 이용하는 열거형)
public enum City {서울, 부산, 대구, 광주, 대전};
// 데이터값을 임의로 지정한 열거형 객체 선언
// 데이터값을 정해 줄 경우에는 생성자를 만들어서 괄호속의 값이 변수에 저장되도록 해야한다.
public enum Season{
봄("3월부터 5월까지"), 여름("6월부터 8월까지"), 가을("9월부터 11월까지"), 겨울("12월부터 2월까지");
// 괄호속의 값이 저장될 변수 선언
private String data;
// 생성자 만들기(열거형의 생성자는 제어자가 묵시적으로 'private'이다.)
// private으로 class에서만 접근이 가능하여 다른 것을 추가하는 걸 방지한다.
Season(String data) {
this.data = data;
}
// getter메서드
public String getData() {
return data;
}
}
public static void main(String[] args) {
/*
* 열거형에서 사용되는 주요 메서드
*
* 1. name() => 열거형 상수객체의 이름을 문자열로 반환한다.
* 2. ordinal() => 열거형 상수가 정의된 순서값을 반환한다. (기본적으로 0부터 시작함)
* 3. valueOf("열거형상수이름") => 지정된 열거형에서 '열거형상수이름'과 일치하는 열거형 상수객체를 반환한다.
*/
City myCity1; // 열거형 객체변수 선언
City myCity2; // 열거형 객체변수 선언
myCity1 = City.서울;
myCity2 = City.valueOf("서울");
System.out.println("myCity1 : " + myCity1.name());
System.out.println("myCity1의 ordinal : " + myCity1.ordinal());
System.out.println();
System.out.println("myCity2 : " + myCity2.name());
System.out.println("myCity2의 ordinal : " + myCity2.ordinal());
System.out.println("===========================================");
Season ss = Season.valueOf("여름");
System.out.println("name => " + ss.name());
System.out.println("ordinal => " + ss.ordinal());
System.out.println("getter메서드 호출 => " + ss.getData());
System.out.println("--------------------------------------------");
// 열거형이름.values() => 열거형 상수 배열로 가져온다.
Season[] enumArr = Season.values();
for (Season s : enumArr) {
System.out.println(s.name() + " : " + s.getData());
}
System.out.println();
for (City city : City.values()) {
System.out.println(city + " : " + city.ordinal());
}
System.out.println("===========================================");
City city = City.대구;
System.out.println(city == City.대전);
System.out.println(city == City.대구);
System.out.println();
System.out.println("대구 => " + city.compareTo(City.대구)); // index 값을 비교하여 뻄
System.out.println("서울 => " + city.compareTo(City.서울));
System.out.println("대전 => " + city.compareTo(City.대전));
}
}
public static <타입글자 extends 제한할타입> 리턴타입 메소드 이름(클래스<타입글자> 파라미터명)
package kr.or.ddit.basic;
class Util2 {
public static <T extends Number> int compare(T t1, T t2) {
double v1 = t1.doubleValue();
double v2 = t2.doubleValue();
// v1이 크면 양수, v1이 작으면 음수 출력
return Double.compare(v1, v2);
}
}
public class T04GenericMethodTest {
public static void main(String[] args) {
int result1 = Util2.compare(10, 20);
System.out.println(result1);
System.out.println();
int result2 = Util2.compare(3.14, 3);
System.out.println(result2);
System.out.println();
// 숫자 타입이 아니기에 오류 발생
// System.out.println(Util2.compare("C", "JAVA"));
}
}
결과 화면4
package kr.or.ddit.basic;
import java.util.ArrayList;
import java.util.List;
public class T05WildCardTest {
public static void main(String[] args) {
FruitBox<Fruit> fruitBox = new FruitBox<>(); // 과일상자
FruitBox<Apple> appleBox = new FruitBox<>(); // 사과상자
fruitBox.add(new Apple());
fruitBox.add(new Grape());
appleBox.add(new Apple());
appleBox.add(new Apple());
// appleBox.add(new Grape()); // 사과만 넣을 수 있는데 다른 것을 넣으려고 해서 에러 발생.
}
}
class Fruit {
private String name; // 과일 이름
public Fruit(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "과일(" + name + ")";
}
}
class Apple extends Fruit {
public Apple() {
super("사과");
}
}
class Grape extends Fruit {
public Grape() {
super("포도");
}
}
// 과일상자 클래스
class FruitBox<T>{
private List<T> fruitList;
public FruitBox() {
fruitList = new ArrayList<>();
}
public List<T> getFruitList() {
return fruitList;
}
public void add(T fruit) {
fruitList.add(fruit);
}
}
package kr.or.ddit.basic;
import java.util.ArrayList;
import java.util.List;
public class T05WildCardTest {
public static void main(String[] args) {
FruitBox<Fruit> fruitBox = new FruitBox<>(); // 과일상자
FruitBox<Apple> appleBox = new FruitBox<>(); // 사과상자
fruitBox.add(new Apple());
fruitBox.add(new Grape());
appleBox.add(new Apple());
appleBox.add(new Apple());
// appleBox.add(new Grape()); // 사과만 넣을 수 있는데 다른 것을 넣으려고 해서 에러 발생.
Juicer.makeJuice(fruitBox);
// Fruit 타입만 허용하는데, Apple 타입을 넣었기에 에러 발생
// => makeJuice와 그 안에 있는 for 타입을 제너릭으로 변환해야함
Juicer.makeJuice(appleBox);
}
}
class Juicer {
static <T extends Fruit> void makeJuice(FruitBox<T> box) {
// static void makeJuice(FruitBox<Fruit> box) {
String fruitListsStr = ""; // 과일 목록
int cnt = 0;
for (T f : box.getFruitList()) {
if(cnt == 0) {
fruitListsStr += f;
} else {
fruitListsStr += ", " + f;
}
cnt++;
}
System.out.println(fruitListsStr + " => 주스 완성!!!");
}
}
class Fruit {
private String name; // 과일 이름
public Fruit(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "과일(" + name + ")";
}
}
class Apple extends Fruit {
public Apple() {
super("사과");
}
}
class Grape extends Fruit {
public Grape() {
super("포도");
}
}
// 과일상자 클래스
class FruitBox<T>{
private List<T> fruitList;
public FruitBox() {
fruitList = new ArrayList<>();
}
public List<T> getFruitList() {
return fruitList;
}
public void add(T fruit) {
fruitList.add(fruit);
}
}
결과 화면5
와일드카드 (Wild Card)
: 제너릭 타입을 이용한 타입으로, 변수 선언과 객체 생성 및 메서드를 정의할 때 사용된다.
결정되지 않은 타입을 선언하기 위해 사용.
=> 와일드카드로 인해 무조건 제너릭 타입을 위해 제너릭 메소드를 사용하지 않아도 됨. (일반 메소드 사용 가능)
사용 방법
<? extends 타입> => 와일드카드의 상한 제한. T와 그 자손들만 가능
<? super 타입> => 와일드카드의 하한 제한. T와 그 조상들만 가능
<?> => 모든 허용가능한 타입이 가능
ex)
List<?> list = new ArrayList<Integer>();
package kr.or.ddit.basic;
import java.util.ArrayList;
import java.util.List;
public class T05WildCardTest {
/*
* 와일드 카드에 대하여...
*
* 와일드카드(?)는 제너릭 타입을 이용한 타입.
* 안전한 코드를 위해 사용되는 특별한 종류의 인수(Argument)로서,
* 변수 선언, 객체생성 및 메서드를 정의할 때 사용된다.
*
* <? extends T> => 와일드카드의 상한 제한. T와 그 자손들만 가능
* <? super T> => 와일드카드의 하한 제한. T와 그 조상들만 가능
* <?> => 모든 허용가능한 타입이 가능
*/
public static void main(String[] args) {
FruitBox<Fruit> fruitBox = new FruitBox<>(); // 과일상자
FruitBox<Apple> appleBox = new FruitBox<>(); // 사과상자
fruitBox.add(new Apple());
fruitBox.add(new Grape());
appleBox.add(new Apple());
appleBox.add(new Apple());
Juicer.makeJuice(fruitBox);
Juicer.makeJuice(appleBox);
}
}
class Juicer {
static void makeJuice(FruitBox<? extends Fruit> box) { // 일반 메소드
// static <T extends Fruit> void makeJuice(FruitBox<T> box) { // 제너릭 메소드
String fruitListsStr = ""; // 과일 목록
int cnt = 0;
for (Object f : box.getFruitList()) {
if(cnt == 0) {
fruitListsStr += f;
} else {
fruitListsStr += ", " + f;
}
cnt++;
}
System.out.println(fruitListsStr + " => 주스 완성!!!");
}
}
class Fruit {
private String name; // 과일 이름
public Fruit(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "과일(" + name + ")";
}
}
class Apple extends Fruit {
public Apple() {
super("사과");
}
}
class Grape extends Fruit {
public Grape() {
super("포도");
}
}
// 과일상자 클래스
class FruitBox<T>{
private List<T> fruitList;
public FruitBox() {
fruitList = new ArrayList<>();
}
public List<T> getFruitList() {
return fruitList;
}
public void add(T fruit) {
fruitList.add(fruit);
}
}
결과 화면1
package kr.or.ddit.basic;
import java.util.ArrayList;
import java.util.List;
public class T06WildCardTest {
// 장바구니 항목 조회를 위한 메서드(모든 항목을 담은 장바구니)
public static void displayCartItemInfo(Cart<?> cart) {
System.out.println("= 음식류 장바구니 항목 리스트 =");
for (Object obj : cart.getCartList()) {
System.out.println(obj);
}
System.out.println("------------------------------------");
}
// 장바구니 항목 조회를 위한 메서드(음료나 그 하위 항목을 담은 장바구니)
public static void displayCartItemInfo2(Cart<? extends Drink> cart) {
System.out.println("= 음료나 그 하위 장바구니 항목 리스트 =");
for (Object obj : cart.getCartList()) {
System.out.println(obj);
}
System.out.println("------------------------------------");
}
// 장바구니 항목 조회를 위한 메서드(고기나 그 상위 항목을 담은 장바구니)
public static void displayCartItemInfo3(Cart<? super Meat> cart) {
System.out.println("= 고기나 그 상위 장바구니 항목 리스트 =");
for (Object obj : cart.getCartList()) {
System.out.println(obj);
}
System.out.println("------------------------------------");
}
public static void main(String[] args) {
Cart<Food> foodCart = new Cart<>();
foodCart.addItem(new Meat("돼지고기", 10000));
foodCart.addItem(new Meat("소고기", 20000));
foodCart.addItem(new Juice("오렌지주스", 1500));
foodCart.addItem(new Coffee("아메리카도", 1500));
Cart<Meat> meatCart = new Cart<>();
meatCart.addItem(new Meat("돼지고기", 10000));
meatCart.addItem(new Meat("소고기", 20000));
// meatCart.addItem(new Juice("오렌지주스", 1500)); // 타입 지정으로 인해
// meatCart.addItem(new Coffee("아메리카도", 1500)); // 담을 수 없음
Cart<Drink> drinkCart = new Cart<>();
// drinkCart.addItem(new Meat("돼지고기", 10000)); // 타입 지정으로 인해
// drinkCart.addItem(new Meat("소고기", 20000)); // 담을 수 없음
drinkCart.addItem(new Juice("오렌지주스", 1500));
drinkCart.addItem(new Coffee("아메리카도", 1500));
displayCartItemInfo(foodCart);
displayCartItemInfo(meatCart);
displayCartItemInfo(drinkCart);
System.out.println("\n\n========================================================");
// 음료나 그 하위 항목
// displayCartItemInfo2(foodCart);
// displayCartItemInfo2(meatCart);
displayCartItemInfo2(drinkCart);
System.out.println("\n\n========================================================");
// 고기나 그 상위 항목
displayCartItemInfo3(foodCart);
displayCartItemInfo3(meatCart);
// displayCartItemInfo3(drinkCart);
}
}
class Food {
private String name;
private int price;
public Food(String name, int price) {
super();
this.name = name;
this.price = price;
}
@Override
public String toString() {
return this.name + "(" + this.price + "원)";
}
}
class Meat extends Food {
public Meat(String name, int price) {
super(name, price);
}
}
class Drink extends Food {
public Drink(String name, int price) {
super(name, price);
}
}
class Juice extends Drink {
public Juice(String name, int price) {
super(name, price);
}
}
class Coffee extends Drink {
public Coffee(String name, int price) {
super(name, price);
}
}
/**
* 장바구니 클래스
* @param <T>
*/
class Cart<T> {
private List<T> cartList;
public Cart() {
cartList = new ArrayList<>();
}
public List<T> getCartList() {
return cartList;
}
public void addItem(T item) {
cartList.add(item);
}
}