//////
Search
🍇

[0930] Math/Calendar클래스, 래퍼 클래스, 제네릭, 제네릭 메소드

생성일
태그
TodayILearn
java
생성일 1

Math 클래스

수학에서 자주 사용하는 절대값, 반올림, 지수나 로그, 연산, 랜덤을 위한 메소드이다.
올림(Floor()) & 내림 (celi()) & 반올림(round())
public class MathEx1 { public static void main(String[] args) { Math.ceil(9.0) // 9 Math.ceil(9.4) // 10 Math.ceil(9.000001) // 10 Math.floor(9.0) // 9 Math.floor(9.9) // 9 Math.round(11.0) // 11 Math.round(11.4) // 11 Math.round(11.5) // 12 } }
Java
복사
랜덤(random())
public class MathEx2 { public static void main(String[] args) { int val = (int)(Math.random() * 100); int dice = (int)(Math.random() * 6) + 1; } }
Java
복사
Math.random() 의 값은 0 이상 1미만의 double 값은 반환
x100을하면 0이상 100미만의 값이 반환
절대값(abs())
public class MathEx3 { int a = 5 int b = 100 System.out.print(b-a) Systme.out.print(Math.abs(a-b)); }
Java
복사
삼각함수(sin(), cos(), tan())

Calendar 클래스

Date 클래스와 더불어 날짜와 시간을 다루는 내장 클래스
Calendar d = Calendar.getInstance(); System.out.println(d.get(Calendar.YEAR)+"년"); System.out.println(d.get(Calendar.MONTH)+1+"월"); System.out.println(d.get(Calendar.DATE)+"일"); d.set(Calendar.YEAR, 1996); d.set(Calendar.MONTH, 6); d.set(Calendar.DATE, 13); System.out.println(d.get(Calendar.YEAR)+"년"); System.out.println(d.get(Calendar.MONTH)+1+"월"); System.out.println(d.get(Calendar.DATE)+"일");
Java
복사
Calendar 클래스는 현재 시간을 기반으로 객체를 생성할 때, getInstance() 메소드를 활용한다.
객체에는 날짜, 시간이 담겨있고 이는 get() 메소드를 통해 불러올 수 있다.
소괄호 사이에는 불러올 년, 월, 일, 시, 분, 초, 등을 넣을 수 있다.
이때, MONTH를 불러올 때, 1월을 0 부터 불러오기에 1을 더해주어야한다.
객체에 새로운 날짜, 시간을 담고 싶을 떄에는 set() 메소드를 활용할 수 있다.
(단위, 값) 을 넣어 설정 가능하며 이렇게 한 뒤 같은 객체에서 값을 뽑으면 변경됨을 확인 가능하다.

제네릭(Generic)이란?

: 데이터 타입을 일반화시킨 것
파라미터 타입이나 리턴 타입에 대한 정의를 외부로 미룸
타입에 대해 유연성과 안정성을 확보
런타임 환경에 아무런 영향이 없는 컴파일 시점의 전처리 기술

✓ 제네릭을 사용하지 않은 경우

class Apple { public String toString() { return "apple"; } } class Orange { public String toString() { return "orange"; } } class Box { private Object ob; public void set(Object o) { ob = o; } public Object get() { return ob; } }
Java
복사
Box 객체의 인스턴스 변수인 ob에 Apple 클래스나 Orange 클래스를 대입하려면 형변환 필요
컴파일 오류를 발견하기 힘듦
심지어 컴파일 과정에서 프로그래머의 실수가 발견되지 않을 수 있음

✓ 제네릭을 사용한 경우

class Apple { public String toString() { return "apple"; } } class Orange { public String toString() { return "orange"; } } class Box<T> { private T ob; public void set(T o) { ob = o; } public T get() { return ob; } }
Java
복사
제네릭을 사용하지 않은 경우의 문제점 해결

제네릭 인스턴스 생성

다음과 같은 제네릭 기반의 클래스와 Orange, Apple 클래스가 정의되었다고 하자.
class Box<T> { private T fruit; public void set(T fruit) { this.fruit= fruit; } public T get() { return fruit; } } class Orange{ @Override public String toString() { return "오렌지 입니다."; } } class Apple{ @Override public String toString() { return "사과 입니다."; } }
Java
복사
다음과 같은 형태로 인스턴스를 생성할 수 있다.
클래스명 <참조 자료형> 참조 변수명 = new 클래스명 <참조 자료형>();
Box<Apple> appleBox = new Box<Apple>();
Java
복사
T를 Apple로 결정하여 인스턴스를 생성한 것이다.
Apple 또는 Apple을 상속하는 하위 클래스의 인스턴스를 생성할 수 있다.
용어는 다음과 같다.
Box<T>에서 T : 타입 매개변수(Type Parameter)
Box<Apple>에서 Apple : 타입 인자(Type Argument)
Box<Apple> : 매개변수화 타입(Parameterized Type)

제네릭의 효과

public static void main(String[] args) { Box<Apple> appleBox = new Box<Apple>(); // Apple 형으로 Box 클래스 생성 Box<Orange> orangeBox = new Box<Orange>(); appleBox.set(new Apple()); // 멤버변수 fruit에 Apple의 인스턴스를 입력 orangeBox.set(new Orange()); Apple apple = appleBox.get(); // fruit이 참조하는 주소를 apple에 선언 Orange orange = orangeBox.get(); System.out.println(apple.toString()); System.out.println(orange.toString()); }
Java
복사
Apple apple = appleBox.get();의 코드를 실행할 때 형변환을 하지 않아도 된다.
왜냐하면 Apple 형으로 Box 클래스를 생성하였으므로, Apple 형이 반환되기 때문이다.

제네릭 클래스 자료형 제한

제네릭 클래스에서 T 자료형에 사용할 자료형에 제한을 둘 수 있다.

자료형의 제한이 필요한 이유

class Box<T> { private T fruit; public void set(T fruit) { this.fruit = fruit; } public T get() { return fruit; } } class Orange{ @Override public String toString() { return "오렌지 입니다."; } } class Apple{ @Override public String toString() { return "사과 입니다."; } } class Water{ @Override public String toString() { return "물 입니다."; } } public class BoxTest { public static void main(String[] args) { Box<Apple> appleBox = new Box<Apple>(); Box<Orange> orangeBox = new Box<Orange>(); Box<Water> waterBox = new Box<Water>(); appleBox.set(new Apple()); orangeBox.set(new Orange()); waterBox.set(new Water()); Apple apple = appleBox.get(); Orange orange = orangeBox.get(); Water water = waterBox.get(); System.out.println(apple.toString()); System.out.println(orange.toString()); System.out.println(water.toString()); } }
Java
복사
새로운 클래스 Water를 작성하고, 제네릭 클래스를 활용하여 water의 객체를 출력해보았다.
그러나 실생활에서 Water는 Box에 담기보다는 Bottle에 담는 것이 말이 된다.
이렇듯 제네릭 클래스에 원치 않는 자료형이 오는 것을 막기 위해 자료형을 제한하는 방법을 사용한다.

자료형 제한 방법

추상 클래스와 상속을 이용해 자료형을 제한할 수 있다.
상위 추상 클래스를 만들어 제네릭 클래스를 작성할 때 다음과 같이 활용한다.
abstract class Fruit{ public abstract String toString(); } class Orange extends Fruit{ @Override public String toString() { return "오렌지 입니다."; } } class Apple extends Fruit{ @Override public String toString() { return "사과 입니다."; } } class Box<T extends Fruit> { private T fruit; public void set(T fruit) { this.fruit = fruit; } public T get() { return fruit; } }
Java
복사
Box 클래스에서 <T extends Fruit>을 통해 Fruit 클래스를 상속받은 자료형만 <T>에 올 수 있게 된다.

래퍼클래스(Wrapper Class)

래퍼클래스란?

기본 자료타입(primitive type)을 객체로 다루기 위해서 사용하는 클래스

래퍼클래스의 종류

래퍼 클래스는 java.lang 패키지에 포함되어 있다.
기본 타입에 대응되는 래퍼 클래스들이 있다.

박싱 (Boxing) 과 언박싱 (UnBoxing)

래퍼 클래스는 산술 연산을 위해 정의된 클래스가 아니기 때문에 저장된 값을 변경할수 없다.
값의 참조를 위해서는 인스턴스를 생성 후 생성된 인스턴스의 값 만을 참조 할 수 있다.
박싱 : 기본타입의 데이터 → 래퍼클래스의 인스턴스로 변환
자동 박싱 (AutoBoxing) 과 자동 언박싱 (AutoUnBoxing)
언박싱 : 래퍼클래스의 인스턴스에 저장된 값 → 기본타입의 데이터로 꺼냄
public class Wrapper_Ex { public static void main(String[] args) { Integer num = new Integer(17); // 박싱 int n = num.intValue(); //언박싱 System.out.println(n); } }
Java
복사

제네릭 메소드

클래스 안에 메소드가 있듯이, 제네릭 클래스 안에도 제네릭 메소드를 정의합니다.
단, 제네릭 타입은 한 개의 로직으로 여러 타입을 사용할 수 있도록 해주는데요.
따라서 제네릭 메소드는 한 개의 로직으로 여러 타입의 인자와 리턴 타입을 가질 수 있는 메소드 입니다.

정의 방법

makeBox라는 이름을 가진 제네릭 함수의 선언부 입니다.
<T> : 매개 변수 위치에 제네릭 타입이 들어올 때, 이 함수가 제네릭 메소드라는 걸 알립니다.
Box<T> : 메소드의 리턴 타입
(T o) : 제네릭 타입의 매개변수(파라미터)

제네릭 메소드 사용

1.
제네릭 메소드를 호출할 때, 제네릭 타입이 정해집니다.
2.
타입 인자는 생략이 가능
매개 변수로 받은 값 “Sweet”과 7.59를 컴파일러가 확인하고 자동으로 생성해주기 때문입니다.