Java

[고급자바] Arg, enum(열거형), generic(제네릭)

elog 2023. 3. 4. 06:00

1. Arg

가변형 인수

: 메서드의 인수 개수가 호출할 때마다 다를 때 사용한다.

- 가변형 인수는 메서드 안에서는 배열로 처리된다.

- 가변형 인수는 한가지 자료형만 사용할 수 있다.

- 가변형 인수와 일반적인 인수를 같이 사용할 경우에는 가변형 인수를 제일 뒤쪽에 배치해야 한다.

 

A. sumArr

public int sumArr(int[] data ) {
	int sum = 0;
	for (int i = 0; i < data.length; i++) {
		sum += data[i];
	}
	return sum;
}
ArgTest test = new ArgTest();
//방법1
//int[] nums = {100, 200, 300};

//방법2
//int[] nums;
//nums = new int[] {100, 200, 300};
		
//방법3
int[] nums = new int[] {100, 200, 300};

System.out.println("<sumArr>");
System.out.println(test.sumArr(nums));
System.out.println(test.sumArr(new int[]{1,2,3,4,5})); // 1,2,3,4,5

 

B. sumArg

public int sumArg(int...data) {
	int sum = 0;
	for (int i = 0; i < data.length; i++) {
		sum += data[i];
	}
	return sum;
}
System.out.println("<sumArg>");
System.out.println(test.sumArg(100,200,300));
System.out.println(test.sumArg(1,2,3,4,5));

 

C. sumArg2

public String sumArg2(String name, int...data) {
	int sum = 0;
	for (int i = 0; i < data.length; i++) {
		sum += data[i];
	}
	return name +"씨 점수 : " + sum;
}
System.out.println("<sumArg2>");
System.out.println(test.sumArg2("홍길동", 90, 85,95));

 

D. 전체코드

public class ArgTest {
	// 메서드 만들기
	public int sumArr(int[] data ) {
		int sum = 0;
		for (int i = 0; i < data.length; i++) {
			sum += data[i];
		}
		return sum;
	}
	
	// 가변형 인수용 메서드 만들기
	public int sumArg(int...data) {
		int sum = 0;
		for (int i = 0; i < data.length; i++) {
			sum += data[i];
		}
		return sum;
	}
	
	public String sumArg2(String name, int...data) {
		int sum = 0;
		for (int i = 0; i < data.length; i++) {
			sum += data[i];
		}
		return name +"씨 점수 : " + sum;
	}
	
	public void myMethod(int a) {
		
	}
	
	public static void main(String[] args) {
		ArgTest test = new ArgTest();
		
//		int[] nums = {100, 200, 300};	// 방법1
		
//		int[] nums;	// 방법2
//		nums = new int[] {100, 200, 300};
		
		int[] nums = new int[] {100, 200, 300};	// 방법3
		
		System.out.println("<sumArr>");
		System.out.println(test.sumArr(nums));
		System.out.println(test.sumArr(new int[]{1,2,3,4,5})); // 1,2,3,4,5
		System.out.println();
		
//		int b = 100;
//		test.myMethod(b);
//		test.myMethod(200);
		System.out.println("<sumArg>");
		System.out.println(test.sumArg(100,200,300));
		System.out.println(test.sumArg(1,2,3,4,5));
		System.out.println();
		
		System.out.println("<sumArg2>");
		System.out.println(test.sumArg2("홍길동", 90, 85,95));
	}
}

2. enum(열거형)

- 서로 관련있는 상수들의 집합

- 클래스처럼 보이게 하는 상수

- 열거형은 클래스처럼 독립된 Java 파일에 만들 수 있고, 하나의 Java 파일에 클래스와 같이 만들 수 있고, 클래스 안에 내부 클래스처럼 만들 수 있다.

 

A. 열거형의 속성 및 메서드

name() : 열거형 상수의 이름을 문자열로 반환한다.

ordinal() : 열거형 상수가 정의된 순서값(index)을 반환한다. (0부터 시작)

열거형이름.valueOf("열거형상수명") : 지정된 열거형에서 '열거형상수명'과 일치하는 열거형 상수를 반환한다.

열거형이름.상수명 : valueOf() 메서드와 같다.

열거형이름.values() : 모든 열거형 상수들을 배열로 반환한다.

 

B. 열거형 선언하기

방법 1)

enum 열거형이름 {상수명1, 상수명2, 상수명, ... }

 

방법 2)

enum 열거형이름 {
	상수명1(값들, ...),
    상수명2(값들, ...),
    ...
    상수명n(값들, ...);
    
    // '값들'이 저장될 변수들 선언
    private 자료형이름 변수명;
    ...
    
    // 열거형의 생성자를 만든다.
    // 열거형의 생성자는 '열거형 상수'의 '값들'을 변수에 셋팅하는 역할을 한다.
    // 열거형 생성자는 묵시적으로 private이다.
    
    // '변수명'의 개수는 '값들'의 개수와 같고, 자료형도 각각 맞아야 된다.
    private 열거형이름(자료형 변수명,...) {
    	// 위에 선언된 변수들을 초기화한다.
        ...
    }
    
    // 구성된 '값들'을 외부에서 불러올 수 있는 getter 메서드를 만든다.
    
}


C. 전체 코드

public class EnumTest {
	public enum Color { RED, GREEN, BLUE }
	
	public enum Count { ONE, TWO, THREE }
	
	public enum Season { 
		// 상수명(값들)형식의 선언
		봄("3월부터 5월까지", 15),
		여름("6월부터 8월까지", 32),
		가을("9월부터 11월까지", 17),
		겨울("12월부터 2월까지", -4);
		
		// '값들'이 저장될 변수들 선언
		private String span;
		private int temp;
		
		// 생성자
		Season(String span, int temp) {	// ==> private Season(String span, int temp) 와 같다.
			this.span = span;
			this.temp = temp;
		}
		
		// getter 메서드 만들기
		public String getSpan() {
			return this.span;
		}
		
		public int getTemp() {
			return this.temp;
		}
	}
	
	public static void main(String[] args) {
//		System.out.println("RED : " + ConstTest.RED);
//		System.out.println("THREE : " + ConstTest.THREE);
//		
//		if (ConstTest.RED == ConstTest.THREE) {
//			System.out.println(".....");
//		} else {
//			System.out.println("@@@@@");
//		}
		
		Color mycol = Color.valueOf("RED");	// Color.RED와 같다.
		Count mycnt = Count.THREE;	// Count.valueOf("THREE");와 같다.
		
		System.out.println("mycol : " + mycol.name());
		System.out.println("mycnt : " + mycnt.name());
		System.out.println();
		
		System.out.println("mycol ordinal : " + mycol.ordinal());
		System.out.println("mycnt ordinal : " + mycnt.ordinal());
		System.out.println();
		
		// 서로 다른 종류의 열거형끼리의 비교는 불가하다.
//		if (mycol == mycnt) {
//			System.out.println("....");
//		}
		
		if (mycol == Color.RED) {
			System.out.println("같다");
		}
		System.out.println();
		
		// switch의 case문에 열거형을 배치할 때는 '열거형이름'을 생략하고
		// 상수명만 기술해야 한다.
		switch (mycnt) {
		case ONE : System.out.println("ONE"); break;
		case TWO : System.out.println("TWO"); break;
		case THREE : System.out.println("THREE"); break;
		}
		System.out.println("--------------------------");
		
		Season ss = Season.valueOf("봄");
		System.out.println("name : " + ss.name());
		System.out.println("ordinal : " + ss.ordinal());
		System.out.println("span : " + ss.getSpan());
		System.out.println("temp : " + ss.getTemp());
		System.out.println();
		
		for(Color col : Color.values()) {
			System.out.println(col + " ==> " + col.ordinal());
		}
		System.out.println();
		
		for(Season s : Season.values()) {
			System.out.println(s.name() + " == " + s + " ==> " + s.getSpan() 
								+ "의 평균온도 : " + s.getTemp() + "도");
		}
	} // main문
} // EnumTest

Color mycol = Color.valueOf("RED");	// Color.RED와 같다.
Count mycnt = Count.THREE;	// Count.valueOf("THREE");와 같다.
System.out.println("mycol : " + mycol.name());
System.out.println("mycnt : " + mycnt.name());

System.out.println("mycol ordinal : " + mycol.ordinal());
System.out.println("mycnt ordinal : " + mycnt.ordinal());

if (mycol == Color.RED) {
	System.out.println("같다");
}

switch (mycnt) {
case ONE : System.out.println("ONE"); break;
case TWO : System.out.println("TWO"); break;
case THREE : System.out.println("THREE"); break;
}

Season ss = Season.valueOf("봄");

System.out.println("name : " + ss.name());
System.out.println("ordinal : " + ss.ordinal());
System.out.println("span : " + ss.getSpan());
System.out.println("temp : " + ss.getTemp());

for(Color col : Color.values()) {
	System.out.println(col + " ==> " + col.ordinal());
}

for(Season s : Season.values()) {
	System.out.println(s.name() + " == " + s + " ==> " + s.getSpan() + "의 평균온도 : " 
    			+ s.getTemp() + "도");
}


3. generic(제네릭)

A. 제네릭을 사용하지 않는 class

class NonGeneric {
	private Object value;
	
	public Object getValue() {
		return value;
	}

	public void setValue(Object value) {
		this.value = value;
	}
	
	public NonGeneric(Object value) {
		super();
		this.value = value;
	}

	public NonGeneric() {
		super();
	}
}

 

B. 제네릭 클래스 만드는 방법

형식)

Class 클래스명<제네릭타입 문자> {
	제네릭타입문자 변수명;	// 변수 선언에 제네릭을 사용할 경우
	...
	제네릭타입문자 메서드명() {	// 반환값이 있는 메서드에 제네릭 사용하는 경우
		...
		return 반환값;
	}
	
	// 메서드의 매개변수에 제네릭을 사용하는 경우
	void 메서드명(제네릭타입문자 변수명1, ...) {
		...
	}
}

 

제네릭 타입 글자)

- T : Type

- K : Key

- V : Value

- E : Element (자료구조에 들어가는 데이터)

 

C. 전체코드

class MyGeneric<T> {
	private T value;		// 변수 선언
	
	public T getValue() {	// 반환값 타입
		return value;
	}

	public void setValue(T value) {	// 매개변수
		this.value = value;
	}
}

public class GenericTest {
	
	public static void main(String[] args) {
		NonGeneric ng1 = new NonGeneric();
		ng1.setValue("가나다라");
		
		NonGeneric ng2 = new NonGeneric();
		ng2.setValue(100);
		
		String sTemp = (String)ng1.getValue();
		int iTemp = (int)ng2.getValue();
		System.out.println("문자열 반환값 : " + sTemp);
		System.out.println("정수형 반환값 : " + iTemp);
		System.out.println();
		
//		String sTemp2 = (String)ng2.getValue();]
		System.out.println("-----------------------------------------------------");
		
		MyGeneric<String> mg1 = new MyGeneric<>();
		mg1.setValue("안녕하세요.");
		
		MyGeneric<Integer> mg2 = new MyGeneric<>();
		mg2.setValue(500);
		
		sTemp = mg1.getValue();
		iTemp = mg2.getValue();
		System.out.println("제네릭 문자열 반환값 : " + sTemp);
		System.out.println("제네릭 정수형 반환값 : " + iTemp);
		
//		String sTemp3 = mg2.getValue();
		
	} // main문
} // GenericTest