< 김영한의 실전 자바 - 중급편 > 강의를 보고 이해한 내용을 바탕으로 합니다.
자바는 객체 지향 언어이지만 자바 안에 객체가 아닌 것이 있다.
바로 기본형이다. -- int, double.. 등
기본형은 객체가 아니기 때문에 다음과 같은 한계가 있다.
래퍼 클래스는 기본형을 객체로 감싸서 더 편리하게 사용하도록 도와준다.
즉, 래퍼 클래스는 기본형의 객체 버전이다.
자바는 기본형에 대응하는 래퍼 클래스를 기본으로 제공한다.
그리고 자바가 제공하는 기본 래퍼 클래스는 불변이며 equals로 비교해야 한다는 특징을 가진다.
래퍼클래스.valueOf()를 사용해서 객체를 생성한다. --Integer.valueOf(10)래퍼 클래스에 들어있는 기본형 값을 다시 꺼내는 메서드.
(박스에 들어있는 물건을 꺼내는 것 같다고 해서 언박싱이다.)
--intValue(), doubleValue()
래퍼 클래스는 객체를 그대로 출력해도 내부에 있는 값을 문자로 출력하도록 toString()도 재정의 되어있다.
public static void main(String[] args) {
// Primitive -> Wrapper
int value = 7;
Integer boxedValue = Integer.valueOf(value);
// Wrapper -> Primitive
int unboxedValue = boxedValue.intValue();
System.out.println("boxedValue = " + boxedValue); //boxedValue = 7
System.out.println("unboxedValue = " + unboxedValue); //unboxedValue = 7
}
위는 기존 박싱, 언박싱 기법.
자바 1.5 부터 오토 박싱, 오토 언박싱을 지원한다.
public static void main(String[] args) {
// Primitive -> Wrapper
int value = 7;
Integer boxedValue = value; // 오토 박싱(Auto-boxing)
// Wrapper -> Primitive
int unboxedValue = boxedValue; // 오토 언박싱(Auto-Unboxing)
System.out.println("boxedValue = " + boxedValue); //boxedValue = 7
System.out.println("unboxedValue = " + unboxedValue); //unboxedValue = 7
}
오토 박싱과 오토 언박싱은 컴파일러가 개발자 대신 valueOf(), xxxValue() 등의 코드를 추가해주는 기능. => 기본형과 래퍼형을 서로 편리하게 변환할 수 있다.
Integer boxedValue = value; //오토 박싱(Auto-boxing)
Integer boxedValue = Integer.valueOf(value); //컴파일 단계에서 추가
int unboxedValue = boxedValue; //오토 언박싱(Auto-Unboxing)
int unboxedValue = boxedValue.intValue(); //컴파일 단계에서 추가
래퍼 클래스는 객체이기 때문에 기본형보다 다양한 기능 제공.
그렇다면 기본형은 왜 제공하는가?
기본형 연산이 래퍼 클래스보다 빠르기 때문이다.
자바에서 Class 클래스는 클래스의 정보(메타데이터)를 다루는데 사용된다.
Class 클래스를 통해 실행중인 자바 애플리케이션 내에서 필요한 클래스의 속성과 메서드에 대한 정보를 조회하고 조작할 수 있다.
Class clazz = String.class; // 1.클래스에서 조회
Class clazz = new String().getClass();// 2.인스턴스에서 조회
Class clazz = Class.forName("java.lang.String"); // 3.문자열로 조회
Class 클래스에는 클래스의 모든 정보가 들어있다.
이 정보를 기반으로 인스턴스 생성하거나 메서드 호출하고 필드의 값 변경이 가능하다.
public static void main(String[] args) throws Exception {
Class helloClass = Class.forName("lang.clazz.Hello");
Hello hello = (Hello) helloClass.getDeclaredConstructor().newInstance();
String result = hello.hello();
System.out.println("result = " + result); //result = hello!
}
getDeclaredConstructor().newInstance()
Class를 사용하면 클래스의 메타 정보를 기반으로 클래스에 정의된 메서드, 필드, 생성자 등을 조회하고 이들을 통해 객체 인스턴스를 생성하거나 메서드를 호출하는 작업을 할 수 있다. => 리플렉션
추가로 애노테이션 정보를 읽어서 특별한 기능을 수행할 수도 있고, 최신 프레임워크들은 이런 기능을 적극 활용한다.
시스템과 관련된 기본 기능들을 제공한다.
수학 문제 해결. 너무 많은 기능을 제공하므로 실제 필요할 때 검색하거나 API 문서 찾아보자.
public static void main(String[] args) {
// 기본 연산 메서드
System.out.println("max(10, 20): " + Math.max(10, 20)); //최대값 max(10, 20): 20
System.out.println("min(10, 20): " + Math.min(10, 20)); //최소값 min(10, 20): 10
System.out.println("abs(-10): " + Math.abs(-10)); //절대값 abs(-10): 10
// 반올림 및 정밀도 메서드
System.out.println("ceil(2.1): " + Math.ceil(2.1)); //올림 ceil(2.1): 3.0
System.out.println("floor(2.7): " + Math.floor(2.7)); //내림 floor(2.7): 2.0
System.out.println("round(2.5): " + Math.round(2.5)); //반올림 round(2.5): 3
// 기타 유용한 메서드
System.out.println("sqrt(4): " + Math.sqrt(4)); //제곱근 sqrt(4): 2.0
System.out.println("random(): " + Math.random()); //0.0 ~ 1.0 사이의
double 값 random(): 0.006347084592260965
}
Math.random()을 사용해도 되지만 Random 클래스를 사용하면 더욱 다양한 랜덤값을 구할 수 있다.
(Math.random()도 내부에서는 Random 클래스를 사용한다. Random 클래스는 java.util 패키지 소속이다.)
public static void main(String[] args) {
Random random = new Random();
//Random random = new Random(1); //seed가 같으면 Random의 결과가 같다.
int randomInt = random.nextInt();
System.out.println("randomInt: " + randomInt); //randomInt: -1316070581
double randomDouble = random.nextDouble(); //0.0d ~ 1.0d
System.out.println("randomDouble: " + randomDouble); //randomDouble: 0.37735342193577215
boolean randomBoolean = random.nextBoolean();
System.out.println("randomBoolean: " + randomBoolean); //randomBoolean: false
// 범위 조회
int randomRange1 = random.nextInt(10); //0 ~ 9까지 출력
System.out.println("0 ~ 9: " + randomRange1); //0 ~ 9: 5
int randomRange2 = random.nextInt(10) + 1; //1 ~ 10까지 출력
System.out.println("1 ~ 10: " + randomRange2); //1 ~ 10: 7
}
랜덤은 내부에서 씨드 값을 사용해서 랜덤 값을 구한다. 이 씨드 값이 같으면 항상 같은 결과가 출력된다.
Random random = new Random(1); //seed가 같으면 Random의 결과가 같다.
Seed가 같으면 실행 결과는 반복 실행해도 같다.