none_generic_type
package sec02_exam01_none_generic_type;
public class Apple {
}
package sec02_exam01_none_generic_type;
public class Box {
private Object object;
public void set(Object object) {
this.object = object;
}
public Object get() {
return object;
}
}
package sec02_exam01_none_generic_type;
public class BoxExample {
public static void main(String[] args) {
Box box = new Box();
box.set("홍길동");
String name = (String) box.get();
box.set(new Apple());
Apple apple = (Apple)box.get();
}
}
generic_type
package sec02.exam02_generic_type;
public class Box <T>{
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
}
package sec02.exam02_generic_type;
public class BoxExample {
//구체적인 타입을 지정하지 않으면, Object로 들어간다. 그래서 타입 지정안하면 경고표시뜨는거임.
public static void main(String[] args) {
//제너릭 타입을 사용하는 것이 프로그램의 성능에 좋은 결과를 가져다준다.
Box<String> box1 = new Box<String>();
box1.set("hello");
String greet = box1.get();
Box<Integer> box2 = new Box<Integer>();
box2.set(6);
int value = box2.get();
}
}
multi_type_parameter
package sex03.exam01_multi_type_parameter;
public class Car {
}
package sex03.exam01_multi_type_parameter;
// alt + shift + s 누르면 자동으로 게터 세터 메소드 생성할 수 있음.
public class Product<T, M> {
private T kind;
private M model;
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 sex03.exam01_multi_type_parameter;
public class Tv {
}
package sex03.exam01_multi_type_parameter;
public class ProductExample {
public static void main(String[] args) {
Product<Tv,String> product1 = new Product<>();
product1.setKind(new Tv());
product1.setModel("스마트TV");
Tv tv = product1.getKind();
String tvModel = product1.getModel();
Product<Car,String> product2 = new Product<>();
product2.setKind(new Car());
product2.setModel("디젤");
Car car = product2.getKind();
String carModel = product2.getModel();
}
}
generic_method1
package sec04.exam01_generic_method;
public class Box <T>{
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
}
package sec04.exam01_generic_method;
public class Util {
//제너릭 메소드. T를 매개변수 타입과 리턴타입에서 사용하겠다는 뜻이다.
public static <T> Box<T> boxing(T t){
Box<T> box = new Box<>();
box.set(t);
return box;
}
}
package sec04.exam01_generic_method;
public class BoxingMethodExample {
public static void main(String[] args) {
//정적 메소드여서 Util. 으로 접근할 수 있다.
Box<Integer> box1 = Util.<Integer>boxing(100);
int intValue = box1.get();
System.out.println(intValue);
Box<String> box2 = Util.boxing("홍길동"); //컴파일러는 유추를 한다. <String>이 있는걸로 해석을 한다.
String strValue = box2.get();
System.out.println(strValue);
}
}
generic_method2
package sec04.exam02_generic_method;
public class Pare<K,V> {
private K key;
private V value;
public Pare(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
}
package sec04.exam02_generic_method;
public class Util {
public static <K, V> boolean compare(Pare<K, V> p1, Pare<K, V> p2) {
boolean keyCompare = p1.getKey().equals(p2.getKey());
boolean valueCompare = p1.getValue().equals(p2.getValue());
return keyCompare && valueCompare;
}
}
package sec04.exam02_generic_method;
public class CompareMethodExample {
public static void main(String[] args) {
Pare<Integer,String> p1 = new Pare<>(1,"사과");
Pare<Integer,String> p2 = new Pare<>(1,"사과");
//Util.<Integer,String>compare(p1, p2);
boolean result1 = Util.<Integer,String>compare(p1, p2); //컴파일러가 유추할 수 있기 때문에 <> 없어도 됨.
if(result1) {
System.out.println("논리적으로 동등한 객체입니다.");
}else {
System.out.println("논리적으로 동등하지 않는 객체입니다.");
}
Pare<String,String> p3 = new Pare<>("user1","홍길동");
Pare<String,String> p4 = new Pare<>("user2","홍길동");
boolean result2 = Util.compare(p3, p4);
if(result2) {
System.out.println("논리적으로 동등한 객체입니다.");
}else {
System.out.println("논리적으로 동등하지 않는 객체입니다.");
}
}
}
bounded_type
package sec05.exam01_bounded_type;
public class Util {
// 정적 메소드 .-> 이름은 compare 타입 파라미터로 매개변수 2개를 선언한다. -> 그래서 리턴타입 앞에 타입파라메터선언부분이 있어야 한다. <T extends ... >
//T만 온게 아니라 extends Number가 있다. java.lang 의 Number는 추상 클래스이다.
public static <T extends Number> int compare(T t1, T t2) { // 꼭 넘버타입으로만 사용해라... 라는 뜻!
double v1 = t1.doubleValue();
double v2 = t2.doubleValue();
return Double.compare(v1, v2); //v1이 작으면 -1 크면 1 같으면 0
}
}
package sec05.exam01_bounded_type;
public class BoundedTypeParameterExample {
public static void main(String[] args) {
int result1 = Util.<Integer>compare(10, 20); //Integer 생략 가능함.
System.out.println(result1);
int result2 = Util.compare(4.5, 3);
System.out.println(result2);
}
}
generic_wild_card
package sec06.exam01_generic_wildcard;
public class Course<T> { // 과정 클래스 어떤 종류의 학생이 올지 모르니 제너릭 타입이다.
private String name;
private T[] students;
public Course(String name,int capacity) {
this.name = name;
//아직 T가 결정되지 않은상태여서 배열만드는 일반적인 방식으로는 못만든다.
//그러므로 일단 오브젝트 타입으로 만들고 난 뒤에T타입으로 바꿔야 한다.
students = (T[])(new Object[capacity]);
}
public String getName() {return name;}
public T[] getStudents() {return students;}
public void add(T t) {
for(int i = 0;i<students.length;i++) {
if(students[i] == null) { //비어있는 곳을 찾아서 새로운 값을 넣어준다.
students[i] = t;
break;
}
}
}
}
package sec06.exam01_generic_wildcard;
public class Person { //일반인
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {return name;}
@Override
public String toString() {
return name;
}
}
package sec06.exam01_generic_wildcard;
public class Student extends Person{ //학생 클래스
public Student(String name) {
super(name);
}
}
package sec06.exam01_generic_wildcard;
public class HighStudent extends Student {
public HighStudent(String name) {
super(name);
}
}
package sec06.exam01_generic_wildcard;
public class Worker extends Person{ //학생 클래스
public Worker(String name) {
super(name);
}
}
package sec06.exam01_generic_wildcard;
import java.util.Arrays;
public class WildCardExample {
public static void registerCourse(Course<?> course) {
System.out.println(course.getName()+"수강생:"+Arrays.toString(course.getStudents()));
}
public static void registerCourseStudent(Course<? extends Student> course) {
//상위 타입 제한
System.out.println(course.getName()+"수강생:"+Arrays.toString(course.getStudents()));
}
public static void registerCourseWorker(Course<? super Worker> course) {
//하위 타입 제한
System.out.println(course.getName()+"수강생:"+Arrays.toString(course.getStudents()));
}
public static void main(String[] args) {
Course<Person> personCourse = new Course<>("일반인 과정",5);
personCourse.add(new Person("일반인"));
personCourse.add(new Person("직장인"));
personCourse.add(new Person("학생"));
personCourse.add(new Person("고등학생"));
Course<Worker> workerCourse = new Course<>("직장인 과정",5);
workerCourse.add(new Worker("직장인"));
Course<Student> studentCourse = new Course<>("학생 과정",5);
studentCourse.add(new Student("학생"));
studentCourse.add(new HighStudent("고등학생"));
Course<HighStudent> highStudentCourse = new Course<>("고등학생 과정",5);
highStudentCourse.add(new HighStudent("고등학생"));
registerCourse(personCourse);
registerCourse(workerCourse);
registerCourse(studentCourse);
registerCourse(highStudentCourse);
System.out.println();
//registerCourseStudent(personCourse);
//registerCourseStudent(workerCourse);
registerCourseStudent(studentCourse);
registerCourseStudent(highStudentCourse);
System.out.println();
registerCourseWorker(personCourse);
registerCourseWorker(workerCourse);
//registerCourseWorker(studentCourse);
//registerCourseWorker(highStudentCourse);
System.out.println();
}
}
generic_extends_implements
package sec07.exam01_generic_extends_implements;
public class Product<T,M> {
private T kind;
private M model;
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;
}
}
class Tv{}
package sec07.exam01_generic_extends_implements;
public class ChildProduct<K,V,C> extends Product<K,V>{ //부모가 제너릭이면 자식도 제너릭
private C company;
public C getCompany() {
return company;
}
public void setCompany(C company) {
this.company = company;
}
}
package sec07.exam01_generic_extends_implements;
public interface Storage<T> { //인터페이스는 객체 사용설명서와 같다.
public void add(T item ,int index); //인덱스 위치에서 추가한다.
public T get(int index); //인덱스 위치에서 찾는다.
}
package sec07.exam01_generic_extends_implements;
//인터페이스가 제너릭이면, 구현 클래스도 제너릭이다.
public class StorageImpl<T> implements Storage<T>{
private T[] array;
public StorageImpl(int capacity) {
array = (T[])(new Object[capacity]);
}
@Override
public void add(T item, int index) {
array[index] = item;
}
@Override
public T get(int index) {
return array[index];
}
}
package sec07.exam01_generic_extends_implements;
public class ChildProductAndStorageExample {
public static void main(String[] args) {
ChildProduct<Tv,String,String> product = new ChildProduct<>();
product.setKind(new Tv());
product.setModel("SmartTV");
product.setCompany("Samsung");
Storage<Tv> storage = new StorageImpl<Tv>(100);
storage.add(new Tv(), 0);
Tv tv = storage.get(0);
}
}
필기 내용
package generic;
/*
<제너릭 타입이란. >
타입을 파라미터로 가지는 클래스와 인터페이스를 말한다.
<제너릭>
클래스를 선언할 떄 타입 파라미터 기술
컴파일 시 타입 파라미터가 구체적인 클래스로 변경됨.
<비제네릭>
Object 타입을 사용함으로써 빈번한 타입 변한 발생 -> 성능 저하
멀티 타입 파라미터
두개 이상의 타입 파라미터를 사용해서 선언할 수 있다.
class<K,V,...>{...}
자바 7부터는 중복된 타입 파라미터를 생략해도 된다.
<> 안에 들어가는거 중복으로 안해도 된다는 뜻.
<제너릭 메소드 >
매개변수 타입과 리턴 타입으로 타입 파라미터를 갖는 메소드를 말한다.
리턴 타입 앞에 <> 기호를 추가하고 타입 파라미터를 기술한다.
타입 파라미터를 리턴타입과 매개변수에 사용한다.
public <T> Box<T> boxing(T t){...}
<타입 파라미터에 지정되는 구체적인 타입을 제한할 필요가 있을 경우 >
상속 및 구현 관계를 이용해서 타입을 제한한다.
public <T extends 상위타입> 리턴타입 메소드(매개변수,...){...}
상위 타입은 클래스 뿐만 아니라 인터페이스도 가능하다. -> 인터페이스라고 해서 extends 대신 implements를 사용하지 않는다.
<타입 파라미터를 대체할 구체적인 타입>
상위 타입이거나 하위 또는 구현 클래스만 지정할 수 있다.
<주의할점>
메소드의 중괄호 {}안에서 타입 파라미터 변수로 사용 가능한 것은 상위 타입의 멤버(필드,메소드)로 제한된다.
하위 타입에만 있는 필드와 메소드는 사용할 수 없다.
와일드카드(?) 타입
제너릭 타입을 매개변수나 리턴타입으로 사용할 때 타입 파라미터를 제한할 목적
<와일드카드 타입의 세가지 형태>
1.제너릭타입<?>: Unbounded Wildcards (제한 없음)
타입 파라미터를 대치하는 구체적인 타입으로 모든 클래스나 인터페이스 타입이 올 수 있다.
2.제너릭타입<? extends 상위타입> : Upper Bounded Wildcards (상위 클래스 제한)
타입 파라미터를 대치하는 구체적인 타입으로 상위 타입이나 하위 타입만 올 수 있다.
2.제너릭타입<? super 하위타입> : Lower Bounded Wildcards (하위 클래스 제한)
타입 파라미터를 대치하는 구체적인 타입으로 하위 탕딥이나 상위 타입이 올 수 있따.
<제너릭 타입의 상속과 구현 >
제너릭 타입을 부모 클래스로 사용할 경우 ->
타입 파라미터는 자식 클래스에도 기술해야 한다.
public class ChildProduct<T,M> extends Product<T,M> {...}
추가적인 타입 파라미터를 가질 수 있다.
public class ChildProduct<T,M,C> extends Product<T,M> {...}
제너릭 인터페이스를 구현할 경우 ->
타입 파라미터는 구현 클래스에도 기술해야 한다.
public class StorageImpl <T> implements Storage<T> {...}
*/
반응형
'Java' 카테고리의 다른 글
[이것이 자바다] 자바 스트림 공부 정리 (0) | 2020.12.24 |
---|---|
[이것이 자바다] 자바 람다식 공부 정리 (0) | 2020.12.22 |
[이것이 자바다] 자바 어노테이션 공부 정리 (0) | 2020.12.20 |
[이것이 자바다] 자바 메모리 공부 정리 (0) | 2020.12.20 |
[이것이 자바다] 자바 enum 공부 정리 (0) | 2020.12.20 |