본문 바로가기
Java

05.04 Wrapper class, 제네릭

by amungstudy 2023. 5. 4.

package ex_wrapper_class;

 

public class WrapperExample {

 

public static void main(String[] args) {

 

//boxing

int a = 10;

 

// java 9 version에서 deprecated로 되어있다.

Integer obj1 = new Integer(a);

//valueof라는 정적멤버 이용해서 객체 생성하자.

obj1 = Integer.valueOf(a);

obj1 = Integer.valueOf("100");

//다른 데이터 타입을 문자열로 변환

String str = String.valueOf(201234);

//자동 boxing

obj1 = 100;

 

//unBoxing

int i = obj1.intValue();

System.out.println(i);

 

//자동 unBoxing

int value = obj1;

System.out.println(value);

 

// valueOf 와 parseType

Integer obj2 = Integer.valueOf("600");

System.out.println(obj2);

obj2 = Integer.valueOf(600);

System.out.println(obj2);

 

//자동 언박싱이 생략

//반환값 Warrper class사용시

int obj3 = Integer.valueOf("700");

//반환값 Int 타입으로 사용시

int obj4 = Integer.parseInt("300");

 

double valueDouble = Double.parseDouble("3.14");

 

boolean booleanValue = Boolean.parseBoolean("false");

 

byte b = 127;

Byte b1 = Byte.valueOf(b);

 

System.out.println(Byte.MIN_VALUE);

System.out.println(Byte.MAX_VALUE);

 

char c = '가';

Character carc = Character.valueOf(c);

// carc = Character.valueOf("A");

 

//부가적인 기능

int result = Integer.compare(10, 20);

// 첫번째 매개변수의 값이 작으면 음수(-1)

// 같으면 0

// 앞의 값이 크면 양수(1)

System.out.println(result);

 

char cha = 'A'; // 65

char zero = '0'; // 48

System.out.println("char compare = " + Character.compare(cha, zero));

// 첫번째 매개변수의 값이 작으면 음수

// 같으면 0

// 앞의 값이 크면 양수

 

// 자동 boxing

Integer i1 = 10;

result = i1.compareTo(5);

System.out.println("result : " + result);

 

//포장 객체의 내부의 값 비교

Double d1 = 3.14;

Double d2 = 3.14;

System.out.println(d1 == d2);

System.out.println(d1); //String 처럼 내용이 출력됨

System.out.println(d2);

System.out.println(d1.equals(d2));

 

//test(Number) - byte short int float long double

test(1);

test(Integer.valueOf("100"));

test(Float.valueOf(3.14f));

test(111111111L);

test(null);

 

/*

test('가');

test("계산 해볼래?");

test(new Object());

*/

} // end main

 

public static void test(Number n) {

if(n!=null) {

System.out.println(n.intValue());

System.out.println(n.longValue());

System.out.println(n.doubleValue());

System.out.println(n.floatValue());

}else {

System.out.println("null 값이 전달");

}

}

 

 

}


제네릭을 사용하는 코드의 이점

컴파일 시 강한 타입 체크 가능

실행 시 타입 에러가 나는 것 방지

컴파일 시에 미리 타입을 강하게 체크해서 에러 사전 방지

타입변환 제거 가능


package generic01_type;

 

public class Apple {

 

}


 

package generic01_type;

 

public class Orange {

 

}


 

package generic01_type;

 

public class Box {

 

private Object obj;

 

//getter setter 추가

// alt + s + r

public Object getObj() {

return obj;

}

 

public void setObj(Object obj) {

this.obj = obj;

}

}


 

package generic01_type;

 

/**

* 제네릭 기호

* E : 요소(Element) 항목 요소

* K : key - 특정 값을 찾기위한 중복되지 않는 값

* V : value -

* T : Type

* N : Number

*

*/

public class ShowBox<T> {

 

private T obj;

 

public T getObj() {

return obj;

}

 

public void setObj(T t) {

this.obj = t;

}

 

 

}

 


package generic01_type;

 

public class BoxExample {

 

public static void main(String[] args) {

Orange orange = new Orange();

 

Apple apple = new Apple();

 

Box box = new Box();

box.setObj(orange);

if(box.getObj() instanceof Orange) {

Orange o = (Orange)box.getObj();

}

 

Box box2 = new Box();

box.setObj(apple);

 

//ShowBox

ShowBox<Orange> orangeBox = new ShowBox<Orange>();

// orangeBox.setObj(apple);

orangeBox.setObj(orange);

Orange o = orangeBox.getObj();

 

ShowBox<Apple> appleBox = new ShowBox<>();

appleBox.setObj(apple);

Apple a = appleBox.getObj();

 

//제너릭은 참조타입 타입으로 지정할 수 있다.

-> 기본타입을 제너릭으로 이용하려면 wrapper class를 사용해야 한다.

// ShowBox<int> intBox; 오류 발생.

}

 

}

 



package generic02_multi;

 

class TV{}

 

public class Car {}

 

 


package generic02_multi;

//제네릭 타입이 2개인 경우

public class Twin<T,M> {

 

private T type;

private M model;

 

//getter setter 추가 alr + s + r

 

public T getType() {

return type;

}

public void setType(T type) {

this.type = type;

}

public M getModel() {

return model;

}

public void setModel(M model) {

this.model = model;

}

 

 

 

}


package generic02_multi;

 

public class TwinExample {

 

public static void main(String[] args) {

Twin<TV,String> twin = new Twin<TV,String>();

TV tv = new TV();

twin.setType(tv);

twin.setModel("LG 스마트 TV");

//잘못된 값이 전달 되는 것을 컴파일 단계에서 체크

// twin.setModel(1);

 

// 컴파일 단계에서 체크된 데이터만 저장되어 있기 때문에

// 값을 읽을 때 체크할 필요가 없음

String model = twin.getModel();

System.out.println(model);

 

Twin<Car,Integer> carTwin = new Twin<>();

carTwin.setType(new Car());

carTwin.setModel(520);

 

}

 

}



package generic03_method;

 

public class Box<T> {

 

private T type;

 

public T getType() {

return type;

}

 

public void setType(T type) {

this.type = type;

}

 

}


 

package generic03_method;

 

class Util{

public static <T> Box<T> boxing(T t) {

Box<T> box = new Box<>();

box.setType(t);

return box;

}

}

 

public class MethodExample {

 

public static void main(String[] args) {

Box<String> box1 = Util.<String>boxing("사과");

String type = box1.getType();

System.out.println(type);

 

// 대입 연산이 이루어질때는 반환 타입을 보고 제네릭 타입을 유추

// method 호출 시 제네릭 지정 생략 가능

Box<String> box2 = Util.boxing("오렌지");

System.out.println(box2.getType());

 

//제네릭메소드는 메소드가 호출되는 시점에 메소드에서 사용할 타입을 정함.

Box<Integer> box3 = Util.boxing(3);

System.out.println(box3.getType());

}

 

}



package generic04_extends;

 

public class Parent<T,M> {

 

private T kind;

private M model;

 

// getter setter alt + s + r

 

public T getKind() {

return kind;

}

public void setKind(T kind) {

this.kind = kind;

}

public M getModel() {

return model;

}

public void setModel(M model) {

this.model = model;

}

 

 

}


package generic04_extends;

//부모의 제네릭 개수만큼 자식 개체에서 정의해줌.

//자식 개체도 필요한경우 제네릭 추가 가능.

//제네릭 순서 상관 없음

public class Child<T,M,C> extends Parent<T,M>{

 

private C company;

 

//getter setter

 

public C getCompany() {

return company;

}

 

public void setCompany(C company) {

this.company = company;

}

 

 

}

 


package generic04_extends;

 

public class Example {

 

public static void main(String[] args) {

Parent<String, String> p1 = new Parent<>();

p1.setKind("TV");

p1.setModel("ES_DES1");

 

Child<String,String,String> child = new Child<>();

child.setKind("Car");

child.setModel("S class");

child.setCompany("Benz");

 

//이때 Company type은 정의하지 않아도 됨.

Parent<String,String> p = new Child<>();

//Company 이용하고 싶으면 타입변환.

Child<String,String,String> c = (Child<String,String,String>)p;

 

System.out.println("==================================");

Storage<Integer> storage = new StorageImpl<>(10);

storage.add(20, 0);

System.out.println(storage.get(0));

storage.add(300, 1);

System.out.println(storage.get(1));

}

}


package generic04_extends;

 

public interface Storage<E> {

//저장소에 아이템 추가

void add(E item, int index);

//저장소에 값 읽기

E get(int index);

}


 

package generic04_extends;

//StorageImpl객체가 생성될때 제네릭 타입이 결정되도록 함.

public class StorageImpl<E> implements Storage<E>{

 

private E[] array;

 

@SuppressWarnings("unchecked") // 경고 억제(노란줄 보기 싫을때..)

public StorageImpl(int capacity) {

Object[] o = new Object[capacity];

//E타입 배열로 강제타입변환.(제너릭타입으로 바로 배열생성불가.)

this.array = (E[])o;

}

 

@Override

public void add(E item, int index) {

this.array[index] = item;

}

 

@Override

public E get(int index) {

return this.array[index];

}

 

 

 

}

 

'Java' 카테고리의 다른 글

05.08 제네릭 와일드카드, Object, 예외처리  (0) 2023.05.08
generic  (0) 2023.05.04
05.03 인터페이스  (0) 2023.05.03
05.02 상속, 다형성,protected 접근 제한자, 추상메소드  (0) 2023.05.02
Book  (0) 2023.05.01