Java공부(코딩)

코딩초보의 자바(Java)공부 17일차 { 래퍼 , Class 클래스 }

동곤일상 2024. 12. 30. 16:17
반응형
오늘은 래퍼클래스에 대해
알아보겠습니다!!!




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