본 글은 김영한 님의 『김영한의 실전 자바 - 중급 1편』 강의를 학습하며 정리한 내용입니다.
강의 자료에 포함된 일부 코드와 이미지를 참고하여 발췌·활용하였습니다.자바 기본기를 제대로 다지고 싶으시다면, 아래 링크에서 강의를 확인해 보세요
『김영한의 실전 자바 - 중급 1편』 보러 가기
본게시물은 파트너스 활동의 일환으로 작성되었으며, 구매 시 소정의 수수료를 받을 수 있습니다.
김영한의 실전 자바 - 중급 1편| 김영한 - 인프런 강의
현재 평점 5.0점 수강생 10,683명인 강의를 만나보세요. 실무에 필요한 자바의 다양한 중급 기능을 예제 코드로 깊이있게 학습합니다. 실무에 필요한 다양한 자바 중급 기능, Object, 불변 객체, String
www.inflearn.com
기본형의 한계
자바는 객체 지향 언어이다. 그런데 int,double 같은 기본형은 객체가 아니다. 기본형은 객체가 아니기 때문에 다음과 같은 한계가 있다.
- 객체가 아님
- 객체는 유용한 메서드를 제공할 수 있는데, 기본형은 객체가 아니므로 메서드를 제공할 수 없다.
- null 값을 가질 수 없음
- 기본형 데이터 타입은 null 값을 가질 수 없다.
- 때로는 데이터가 “없음” 이라는 상태를 나타내야 할 필요가 있는데, 기본형은 항상 값을 가지기 때문에 이런 표현을 할 수 없다.
래퍼 클래스
래퍼 클래스(Wrapper class) 란 특정 기본형을 감싸서 만드는 클래스를 말한다. 래퍼 클래스는 기본형을 객체로 감싸서 더 편리하게 사용하도록 도와주기 때문에 상당히 유용하다.
즉, 래퍼 클래스는 기본형의 객체 버전이다.
자바는 기본형에 대응하는 래퍼 클래스를 기본으로 제공한다.
- byte → Byte
- short → Short
- int → Integer
- long → Long
- float → Float
- double → Double
- char → Character
- boolean → Boolean
래퍼 클래스 특징
- 불변이다.
- equals 로 비교해야 한다.
래퍼 클래스 사용법
public class WrapperClassMain {
public static void main(String[] args) {
Integer newInteger = new Integer(10); //미래에 삭제 예정, 대신에 valueOf() 사용
Integer integerObj = Integer.valueOf(10); //-128 ~ 127 자주 사용하는 숫자값 재사용, 불변
Long longObj = Long.valueOf(100);
Double doubleObj = Double.valueOf(10.5);
System.out.println("newInteger = " + newInteger);
System.out.println("integerObj = " + integerObj);
System.out.println("longObj = " + longObj);
System.out.println("doubleObj = " + doubleObj);
System.out.println("내부 값 읽기");
int intValue = integerObj.intValue(); System.out.println("intValue = " + intValue);
long longValue = longObj.longValue();
System.out.println("longObj = " + longValue);
System.out.println("비교");
System.out.println("==: " + (newInteger == integerObj));
System.out.println("equals: " + newInteger.equals(integerObj));
}
}
---실행결과---
newInteger = 10
integerObj = 10
longObj = 100
doubleObj = 10.5
내부 값 읽기
intValue = 10
longObj = 100
비교
==: false
equals: true
박싱(Boxing) - 래퍼 클래스 생성
기본형을 래퍼 클래스로 변경하는 것을 마치 박스에 물건을 넣는 것 같다고 해서 박싱이라고 한다.
사용법은 아래와 같다.
- new Integer(10) 은 향후 자바에서 제거된다.
- Integer.valueOf(10) 을 사용하면 된다.
- 내부에서 new Integer(10) 을 사용해서 객체를 생성하고 돌려준다.
- 개발자들이 일반적으로 자주 사용하는 -128 ~ 127 범위의 Integer 클래스를 미리 생성해둔다.
- 해당 범위의 값을 조회하면 미리 생성된 Integer 객체를 반환한다.
언박싱(Unboxing)
박스에 들어있는 물건을 꺼내는 것 같다고 해서 언박싱이라 한다. intValue() 는 래퍼 클래스에 들어있는 기본형 값을 다시 꺼내는 메서드이다.
비교
래퍼 클래스는 객체이기 때문에 == 대신 equals() 를 사용해야 한다. 내부의 값을 비교하도록 equals() 를 재정의해뒀다.
toString()
래퍼 클래스는 객체를 그대로 출력해도 내부에 있는 값을 문자로 출력하도록 toString() 을 재정의했다.
래퍼 클래스 - 오토 박싱, 언박싱
개발자들이 오랜기간 개발을 하다 보니 기본형을 래퍼 클래스로 변환하거나 또는 래퍼 클래스를 기본형으로 변환하는 일이 자주 발생해, 이런 문제를 해결하기 위해 자바 1.5부터 오토박싱, 오토언박싱을 지원한다.
오토 박싱, 오토 언박싱
public class AutoboxingMain {
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);
System.out.println("unboxedValue = " + unboxedValue);
}
}
---실행결과---
boxedValue = 7
unboxedValue = 7
오토 박싱과 오토 언박싱은 컴파일러가 개발자 대신 valueOf, xxxValue() 등의 코드를 추가해주는 기능이다.
과정은 아래와 같다.
Integer boxedValue = value; //오토 박싱(Auto-boxing)
Integer boxedValue = Integer.valueOf(value); //컴파일 단계에서 추가
int unboxedValue = boxedValue; //오토 언박싱(Auto-Unboxing)
int unboxedValue = boxedValue.intValue(); //컴파일 단계에서 추가
래퍼 클래스 - 주요 메서드와 성능
메서드
- valueOf() : 래퍼 타입을 반환한다. 숫자, 문자열을 모두 지원한다.
- parseInt() : 문자열을 기본형으로 변환한다.
- compareTo() : 내 값과 인수로 넘어온 값을 비교한다. 내 값이 크면 1 , 같으면 0 , 내 값이 작으면 -1 을 반환한다.
- Integer.sum() , Integer.min() , Integer.max() : static 메서드이다. 간단한 덧셈, 작은 값, 큰 값 연산을 수행한다
parseInt() vs valueOf()
- valueOf(”10”) : 래퍼 타입을 반환
- parseInt(”10”) : 기본형을 반환
성능
래퍼클래스와 기본형을 같이 제공하는 이유는 무엇일까?
연산이 엄청 많은 코드를 각각 실행했다고 해보자. 래퍼클래스에는 필드로 가지고 있는 기본형의 값 뿐만 아니라 자바에서 객체 자체를 다루는데 필요한 객체 메타데이터를 포함하므로 더 많은 메모리를 사용한다.
따라서 기본형이 더 빠른 수행결과를 가진다.
하지만 일반적인 애플리케이션을 만드는 관점에서 보면 이런 부분을 최적화해도 사막의 모레알 하나 정도의 차이가 날 뿐이다. CPU 연산을 아주 많이 수행하는 특수한 경우이거나, 수만 ~ 수십만 이상 연속해서 연산을 수행해야 하는 경우라면 기본형을 사용해서 최적화를 하면 된다. 그렇지 않은 일반적인 경우라면 코드를 유지보수하기 더 나은 것을 선택하면 된다.
Class 클래스
자바에서 Class 는 클래스의 정보(메타데이터)를 다루는데 사용된다. 개발자는 실행 중인 자바 애플리케이션 내에서 필요한 클래스의 속성과 메서드에 대한 정보를 조회하고 조작할 수 있다.
주요 기능
- 타입 정보 얻기: 클래스의 이름, 슈퍼클래스, 인터페이스, 접근 제한자 등과 같은 정보를 조회할 수 있다.
- 리플렉션: 클래스에 정의된 메서드, 필드, 생성자 등을 조회하고, 이들을 통해 객체 인스턴스를 생성하거나 메서드를 호출하는 등의 작업을 할 수 있다.
- 동적 로딩과 생성: Class.forName() 메서드를 사용하여 클래스를 동적으로 로드하고, newInstance() 메서드를 통해 새로운 인스턴스를 생성할 수 있다.
- 애노테이션 처리: 클래스에 적용된 애노테이션(annotation)을 조회하고 처리하는 기능을 제공한다.
예를 들어, String.class 는 String 클래스에 대한 Class 객체를 나타내며, String 클래스에 대한 메타데이터를 조회하거나 조작할 수 있다.
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ClassMetaMain {
public static void main(String[] args) throws Exception {
//Class 조회
Class clazz = String.class; // 1.클래스에서 조회
//Class clazz = new String().getClass();// 2.인스턴스에서 조회
//Class clazz = Class.forName("java.lang.String"); // 3.문자열로 조회
// 모든 필드 출력
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
System.out.println("Field: " + field.getType() + " " + field.getName());
}
// 모든 메서드 출력
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println("Method: " + method);
}
// 상위 클래스 정보 출력
System.out.println("Superclass: " + clazz.getSuperclass().getName());
// 인터페이스 정보 출력
Class[] interfaces = clazz.getInterfaces();
for (Class i : interfaces) {
System.out.println("Interface: " + i.getName());
}
}
}
실행 결과를 보면 String 클래스의 다양한 정보를 확인할 수 있다.
Class 클래스의 주요 기능
- getDeclaredFields(): 클래스의 모든 필드를 조회한다.
- getDeclaredMethods(): 클래스의 모든 메서드를 조회한다.
- getSuperclass(): 클래스의 부모 클래스를 조회한다.
- getInterfaces(): 클래스의 인터페이스들을 조회한다.
Class 조회
- 클래스.class : 클래스에서 조회
- new 클래스().getClass() : 인스턴스에서 조회
- Class.forName(”java.lang.String”) : 문자열로 조회
클래스 생성하기
Class 클래스에는 클래스의 모든 정보가 들어있다. 이 정보를 기반으로 인스턴스를 생성하거나, 메서드를 호출하고, 필도의 값도 변경할 수 있다.
public class Hello {
public String hello() {
return "hello!";
}
}
public class ClassCreateMain {
public static void main(String[] args) throws Exception {
//Class helloClass = Hello.class;
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()
- getDeclaredConstructor() : 생성자를 선택한다.
- newInstance() : 선택된 생성자를 기반으로 인스턴스를 생성한다.
System 클래스
System 클래스는 시스템과 관련된 기본 기능들을 제공한다.
import java.util.Arrays;
public class SystemMain {
public static void main(String[] args) {
// 현재 시간(밀리초)를 가져온다.
long currentTimeMillis = System.currentTimeMillis();
System.out.println("currentTimeMillis: " + currentTimeMillis);
// 현재 시간(나노초)를 가져온다.
long currentTimeNano = System.nanoTime();
System.out.println("currentTimeNano: " + currentTimeNano);
// 환경 변수를 읽는다.
System.out.println("getenv = " + System.getenv());
// 시스템 속성을 읽는다.
System.out.println("properties = " + System.getProperties());
System.out.println("Java version: " +
System.getProperty("java.version"));
// 배열을 고속으로 복사한다.
char[] originalArray = new char[]{'h', 'e', 'l', 'l', 'o'};
char[] copiedArray = new char[5];
System.arraycopy(originalArray, 0, copiedArray, 0, originalArray.length);
// 배열 출력
System.out.println("copiedArray = " + copiedArray);
System.out.println("Arrays.toString = " +
Arrays.toString(copiedArray));
//프로그램 종료 System.exit(0);
}
}
- 표준 입력,출력,오류 스트림 : System.in, System.out, System.err
- 시간 측정 : System.currentTimeMills(), System.nanoTime() 현재 시간을 밀리초, 나노초 단위로 제공
- 환경 변수 : System.getnev() 메서드를 이용하여 OS 에서 설정한 환경 변수의 값을 얻을 수 있음
- 시스템 속성 : System.getProperties() 를 사용해서 현재 시스템 속성을 얻거나, System.getProperty(String key) 로 특정 속성을 얻을 수 있음
- 시스템 속성은 자바에서 사용하는 설정 값
- 시스템 종료 : System.exit(int status) 프로그램을 종료하고, OS 에 프로그램 종료의 상태 코드를 전달
- 상태 코드 0 : 정상 종료
- 상태 코드 0 아님 : 오류나 예외적인 종료
- 배열 고속 복사 : System.arraycopy 시스템 레벨에서 최적화된 메모리 복사 연산을 사용
Math,Random 클래스
Math 클래스
수 많은 수학 문제를 해결해주는 클래스
기본 연산 메서드
- abs(x) : 절대값
- max(a,b) : 최대값
- min(a,b) : 최소값
지수 및 로그 연산 메서드
- exp(x) : e^x 계산
- log(x) : 자연 로그
- log10(x) : 로그 10
- pow(a, b) : a의 b 제곱
반올림 및 정밀도 메서드
- ceil(x) : 올림
- floor(x) : 내림
- rint(x) : 가장 가까운 정수로 반올림
- round(x) : 반올림
삼각 함수 메서드
- sin(x) : 사인
- cos(x) : 코사인
- tan(x) : 탄젠트
기타
- sqrt(x) : 제곱근
- cbrt(x) : 세제곱근
- random() : 0.0과 1.0 사이의 무작위 값 생성
Random 클래스
Random 클래스를 사용하면 더욱 다양한 랜덤값을 구할 수 있다. java.util 패키지 소속이다.
public class RandomMain {
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);
double randomDouble = random.nextDouble(); //0.0d ~ 1.0d
System.out.println("randomDouble: " + randomDouble);
boolean randomBoolean = random.nextBoolean();
System.out.println("randomBoolean: " + randomBoolean);
// 범위 조회
int randomRange1 = random.nextInt(10); //0 ~ 9까지 출력
System.out.println("0 ~ 9: " + randomRange1);
int randomRange2 = random.nextInt(10) + 1; //1 ~ 10까지 출력
System.out.println("1 ~ 10: " + randomRange2);
}
}
- random.nextInt() : 랜덤 int 값을 반환한다.
- nextDouble() : 0.0d ~ 1.0d 사이의 랜덤 double 값을 반환한다.
- nextBoolean() : 랜덤 boolean 값을 반환한다.
- nextInt(int bound) : 0 ~ bound 미만의 숫자를 랜덤으로 반환한다. 예를 들어서 3을 입력하면 0, 1,2 를 반환한다
씨드(Seed)
랜덤은 내부에서 씨드 값을 사용해서 랜덤 값을 구한다. 이 씨드 값이 같으면 항상 같은 결과가 출력된다.
//Random random = new Random();
Random random = new Random(1); //seed가 같으면 Random의 결과가 같다.'인프런 > 김영한 자바' 카테고리의 다른 글
| [김영한의 실전 자바 중급 1편] - 6. 날짜와 시간 (0) | 2025.10.16 |
|---|---|
| [김영한의 실전 자바 중급 1편] - 5. 열거형,ENUM (0) | 2025.10.14 |
| [김영한의 실전 자바 중급 1편] - 3. String 클래스 (0) | 2025.10.10 |
| [김영한의 실전 자바 중급 1편] - 2. 불변 객체 (0) | 2025.10.10 |
| [김영한의 실전 자바 중급 1편] - 1. Object 클래스 (0) | 2025.09.20 |