오늘은 래퍼클래스에 대해
알아보겠습니다!!!
1) 래퍼클래스 - 기본형의 한계
기본형의 한계
자바는 객체 지향 언어이다. 그런데 자바 안에 객체가 아닌 것이 있다.
바로 `int` , `double` 같은 기본형.
기본형은 객체가 아니기 때문에 다음과 같은 한계가 있다.
1)객체가 아님**: 기본형 데이터는 객체가 아니기 때문에, 객체 지향 프로그래밍의 장점을 살릴 수 없다.
예를 들어 객체는 유용한 메서드를 제공할 수 있는데,
기본형은 객체가 아니므로 메서드를 제공할 수 없다.
추가로 객체 참조가 필요한 컬렉션 프레임워크를 사용할 수 없다.
그리고 제네릭도 사용할 수 없다. (이 부분은 뒤에서 설명한다.)
2)null 값을 가질 수 없음**: 기본형 데이터 타입은 `null` 값을 가질 수 없다.
때로는 데이터가 `없음` 이라는 상태를 나타내야 할 필요가 있는데,
기본형은 항상 값을 가지기 때문에 이런 표현을 할 수 없다.
2) 래퍼클래스
래퍼 클래스는 기본형의 객체 버전이다.
자바는 기본형에 대응하는 래퍼 클래스를 기본으로 제공한다.
`byte --> Byte`
`short --> Short`
`int --> Integer`
`long --> Long`
`float --> Float`
`double --> Double`
`char --> Character`
`boolean --> Boolean`
그리고...
자바가 제공하는 래퍼클래스의 특징
1) 불변이다 2) 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));}}
박싱(Boxing)
기본형을 래퍼 클래스로 변경하는 것을 마치 박스에 물건을 넣은 것 같다고 해서
박싱(Boxing)이라 한다.
`new Integer(10)` 은 직접 사용하면 안된다
대신에 `Integer.valueOf(10)` 를 사용하면 된다.
*intValue() - 언박싱(Unboxing)**
래퍼 클래스에 들어있는 기본형 값을 다시 꺼내는 메서드이다.
박스에 들어있는 물건을 꺼내는 것 같다고 해서 언박싱(Unboxing)이라 한다.]
*비교는 equals() 사용**
래퍼 클래스는 객체이기 때문에 `
'=='비교를 하면 인스턴스의 참조값을 비교한다.
래퍼 클래스는 내부의 값을 비교하도록 `equals()` 를 재정의 해두었다.
따라서 값을 비교하려면 `equals()` 를사용해야 한다.
참고로 래퍼클래스는
toString()을 재정의 해
참조값이 아닌 상태를 출력해줌
2-1) 래퍼클래스 - 오토박싱
public class AutoBoxing {
public static void main(String[] args) {
int value = 8;
// Integer boxed = Integer.valueOf(value);
Integer boxed = value; //오토박싱
int compareTo = boxed.compareTo(9);
System.out.println(compareTo); //크면 1 같으면 0 작으면 -1 반환
// int unboxed = integer.intValue();
int unboxed = boxed; // 오토 언박싱
//기본형은 compareto 같은 메서드사용x
System.out.println("boxed : "+boxed);
System.out.println("unboxed : "+unboxed);}}
Integer boxed = value; //오토박싱
이와 같이 Integer.valueof(int)를 생략하고 int만 넣어
오토박싱이 가능함
int unboxed = boxed; // 오토 언박싱
반대의 경우도가능!!
2) 래퍼클래스 - 주요메서드와 기능
public class WrapperUtilMain {
public static void main(String[] args) {
int a = 10;
String b = "20";
Integer i1 = Integer.valueOf(a);
Integer i2 = Integer.valueOf(b);
int bb = Integer.parseInt(b);
//비교연산
int compareTo = i1.compareTo(bb);
System.out.println(" i1 compareTo bb : "+compareTo);
//연산
int sum = Integer.sum(i1, i2);
System.out.println("i1 + i2 = "+sum);
int min = Integer.min(i1, i2);
System.out.println("min = "+min);
int max = Integer.max(i1, i2);
System.out.println("max = "+max);}}
`valueOf()` : 래퍼 타입을 반환한다. 숫자, 문자열을 모두 지원한다.
`parseInt()` : 문자열을 기본형으로 변환한다.
`compareTo()` : 내 값과 인수로 넘어온 값을 비교한다.
내 값이 크면 `1` , 같으면 `0` , 내 값이 작으면 `-1` 을 반환한다.
`Integer.sum()` , `Integer.min()` , `Integer.max()` : `static` 메서드이다. 간단한 덧셈, 작은 값, 큰
값 연산을 수행한다.
3) Class 클래스
`Class` 클래스를 통해 개발자는 실행중인 자바 애플리케이션 내에서
필요한 클래스의 속성과 메서드에 대한 정보를 조회하고 조작할 수 있다
`Class` 클래스의 주요 기능은 다음과 같다.
타입 정보 얻기:
클래스의 이름, 슈퍼클래스, 인터페이스, 접근 제한자 등과 같은 정보를 조회할 수 있다.
**리플렉션
클래스에 정의된 메서드, 필드, 생성자 등을 조회하고, 이들을 통해 객체 인스턴스를 생성하거나
메서드를 호출하는 등의 작업을 할 수 있다.
**동적 로딩과 생성 :
`Class.forName()` 메서드를 사용하여 클래스를 동적으로 로드하고,
`newInstance()`메서드를 통해 새로운 인스턴스를 생성할 수 있다.
**애노테이션 처리:
클래스에 적용된 애노테이션(annotation)을 조회하고 처리하는 기능을 제공한다.
package lang.clazz;
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(); //clazz의 모든 필드 꺼내서 배열에 저장
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());
}}}
Class` 클래스는 다음과 같이 3가지 방법으로 조회할 수 있다.
Class clazz = String.class; // 1.클래스에서 조회
Class clazz = new String().getClass();// 2.인스턴스에서 조회
Class clazz = Class.forName("java.lang.String"); // 3.문자열로 조회
**Class 클래스의 주요 기능**
**getDeclaredFields()**: 클래스의 모든 필드를 조회한다.
**getDeclaredMethods()**: 클래스의 모든 메서드를 조회한다.
**getSuperclass()**: 클래스의 부모 클래스를 조회한다.
**getInterfaces()**: 클래스의 인터페이스들을 조회한다.
클래스 생성하기
public class Hello {
public String Hello() {
return "hello";
}}
/////////////////////////////////////////////////
public class ClassCreateMain {
public static void main(String[] args) throws Exception{
Class helloClass = Class.forName("lang.clazz.Hello");
Hello hello=(Hello)helloClass.getDeclaredConstructor().newInstance();
String string = hello.Hello();
System.out.println(string);}
}
getDeclaredConstructor().newInstance()**
`getDeclaredConstructor()` : 생성자를 선택한다.
`newInstance()` : 선택된 생성자를 기반으로 인스턴스를 생성한다.
4)System 클래스
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.currentTimeMillis()` 와 `System.nanoTime()` 은
현재 시간을 밀리초 또는 나노초 단위로 제공한다.
**환경 변수**: `
System.getenv()` 메서드를 사용하여 OS에서 설정한 환경 변수의 값을 얻을 수 있다.
**시스템 속성**: `System.getProperties()` 를 사용해 현재 시스템 속성을 얻거나
`System.getProperty(String key)`로 특정 속성을 얻을 수 있다.
시스템 속성은 자바에서 사용하는 설정값이다.
**시스템 종료**: `System.exit(int status)` 메서드는 프로그램을 종료하고, OS에 프로그램 종료의 상태 코
드를 전달한다.
상태 코드`0` : 정상 종료
상태 코드`0` 이 아님: 오류나 예외적인 종료
**배열 고속 복사**:
`System.arraycopy` 는 시스템 레벨에서 최적화된 메모리 복사 연산을 사용한다.
직접 반복문을 사용해서 배열을 복사할 때 보다 수 배 이상 빠른 성능을 제공한다.
5)Random , Math 클래스
Math클래스
Math클래스는 수많은 수학문제를 해결해 줄수있는
클래스이다 자주사용하는 메서드를
코드를 통해 알아보자
public class MathMain {
public static void main(String[] args) {
// 기본 연산 메서드
System.out.println("max(10, 20): " + Math.max(10, 20)); //최대값
System.out.println("min(10, 20): " + Math.min(10, 20)); //최소값
System.out.println("abs(-10): " + Math.abs(-10)); //절대값
// 반올림 및 정밀도 메서드
System.out.println("ceil(2.1): " + Math.ceil(2.1)); //올림
System.out.println("floor(2.7): " + Math.floor(2.7)); //내림
System.out.println("round(2.5): " + Math.round(2.5)); //반올림
// 기타 유용한 메서드
System.out.println("sqrt(4): " + Math.sqrt(4)); //제곱근
System.out.println("random(): " + Math.random()); //0.0 ~ 1.0 사이의double 값
}}
Random 클래스
math.random()을 사용해서
랜덤값을 구해도 되지만
Random클래스를 사용하는것이 더 유용함
(math.random()도 내부에서 Random클래스사용)
package lang.random;
import java.util.Random;
public class RandomMain {
public static void main(String[] args) {
Random random = new Random();
int ranInt = random.nextInt();
System.out.println("ranInt : "+ranInt);
double ranDouble = random.nextDouble();
System.out.println("ranDouble : "+ranDouble);
boolean ranBool = random.nextBoolean();
System.out.println("ranBool : "+ranBool);
int ranInt2 = random.nextInt(15); //0~14
System.out.println("ranInt2 : "+ranInt2);
int ranInt3 = random.nextInt(15)+1; //1~15
System.out.println("ranInt3 : "+ranInt3);
}}
출력 (매번 다름)
ranInt : -300112477
ranDouble : 0.573959298143025
ranBool : true
ranInt2 : 2
ranInt3 : 13
`random.nextInt()` : 랜덤 `int` 값을 반환한다.
`nextDouble()` : `0.0d` ~ `1.0d` 사이의 랜덤 `double` 값을 반환한다.
`nextBoolean()` : 랜덤 `boolean` 값을 반환한다.
`nextInt(int bound)` : `0` ~ `bound` 미만의 숫자를 랜덤으로 반환한다.
예를 들어서 3을 입력하면 `0, 1,2` 를 반환한다.
1부터 특정 숫자의 `int` 범위를 구하는 경우 `nextInt(int bound)` 의 결과에 +1을 하면 된다.
씨드 - Seed
Random() 클래는 seed를 통해
랜덤값을 생성
하지만
이 seed값을 고정해놓으면
반복 실행해도
출력결과가 바뀌지않음
Random random = new Random(1);
6) 문제와 풀이
문제1 - parseInt()
**문제 설명**
문자로 입력된 `str1` , `str2` 두 수의 합을 구하자.
public class WrapperTest {
public static void main(String[] args) {
String str1 = "115";
String str2 = "55";
Integer integer1 = Integer.valueOf(str1);
Integer integer2 = Integer.valueOf(str2);
int sum1 = Integer.sum(integer1, integer2);
System.out.println("sum : "+sum1);
//두번쨰 방법
int int1 = Integer.parseInt(str1);
int int2 = Integer.parseInt(str2);
System.out.println("sum : "+(int1+int2))}}
출력
sum : 170
sum : 170
문제2)
배열에 입력된 모든 숫자의 합을 구하자. 숫자는 `double` 형이 입력될 수 있다
public class WrapperTest2 {
public static void main(String[] args) {
String [] array1 = new String[] {"2.5","1.2","3.2","6.7"};
double sum = 0;
for (String s : array1) {
sum+=Double.parseDouble(s);
}
System.out.printf("sum : %.2f ",sum);
}}
출력
sum : 13.60
문제3 - 박싱, 언박싱
`String str` 을 `Integer`로 변환해서 출력해라.
`Integer` 를 `int`로 변환해서 출력해라.
`int` 를 `Integer`로 변환해서 출력해라.
오토 박싱, 오토 언박싱을 사용하지 말고 직접 변환해야 한다
public class NoBoxingtest {
public static void main(String[] args) {
String str = "199";
Integer integer = Integer.valueOf(str);
System.out.println(integer); //String -> Integer
int intValue = integer.intValue(); //Integer --> int
System.out.println(intValue);
Integer valueOf = Integer.valueOf(intValue); //int --> Integer
System.out.println(valueOf);}}
출력
199
199
199
문제3)
로또번호출력
로또 번호를 자동으로 만들어주는 자동 생성기를 만들자
로또 번호는 1~45 사이의 숫자를 6개 뽑아야 한다.
각 숫자는 중복되면 안된다.
실행할 때 마다 결과가 달라야 한다.
클래스
package lang.random.test;
import java.util.Random;
public class Lottogenerator {
Random random = new Random();
private int count; // 전역변수(멤버변수)
int []lotto= new int[6]; //전역변수
public int[] generator() {
while(count < 6) { //count가 6 즉, 변수가6개생성되면 종료
//count는 lotto배열에 들어가있는 변수의 갯수를 의미 lotto.length와는 다름
int num = random.nextInt(45)+1; //1~45의 랜덤한변수
if(isUnique(num)) { //중복이없으면 배열에 넣음
lotto[count] = num;
count++;
}}
return lotto;
}
private boolean isUnique(int num) {
for (int i = 0; i < count; i++) {
if(lotto[i] == num) { //랜덤으로만든 변수와 지금까지 만든변수에 중복이있다면 false반환
return false;
}
}return true;
}}
나중에 프레임워크라는 것을 배울텐데
거기서 대표적으로 Set이라는 중복을 허용하지않는
데이터의 집합이 있습니다.
그 중에 TreeSet 은
크기 순서대로 나열해주는 장점이있어요.
<>: 제네릭메서드
안에 Integer로 타입을 정해주었어요
(이로써 Integer 타입이 들어갈수있음)
그걸 활용한다면
밑에 코드처럼 획기적으로 줄일 수 있어요!!
public class LottoGeneratorTreeSet {
Random rand = new Random();
private Set<Integer> lotto = new TreeSet<>();
public Set<Integer> generator() {
while(lotto.size() < 6) {
int a = rand.nextInt(45)+1;
lotto.add(a);
}
return lotto;
}
}
System.out.println("로또 번호 2 (동일한숫자 입력시 적용X)");
LottoGeneratorTreeSet lo = new LottoGeneratorTreeSet();
Set<Integer> lotto2 = lo.generator();
for (Integer i : lotto2) {
System.out.print(i+" ");
}
로또 번호 2 (동일한숫자 입력시 적용X)
5 13 17 34 39 43
'Java공부(코딩)' 카테고리의 다른 글
코딩초보의 자바(Java)공부 19일차 { 날짜와 시간 } (3) | 2025.01.02 |
---|---|
코딩초보의 자바(Java)공부 18일차 { 열거형 -ENUM - } (0) | 2024.12.31 |
코딩초보의 자바(Java)공부 16일차 { String 클래스 } (4) | 2024.12.29 |
코딩초보의 자바(Java)공부 15일차 { Object클래스 } (2) | 2024.12.25 |
코딩초보의 자바(Java)공부 14일차 { 다형성과 설계 } (5) | 2024.12.24 |