package JavaJungSuk3_Study.Example.java8;
import java.util.ArrayList;
import java.util.List;
public class GenericsExample_1 {
public static void main(String[] args) {
List<Tv> list = new ArrayList<>(); //지네릭스 타입을 선언
list.add(new Tv());
// list.add(new Audio()); //지네릭스 이전에는 컴파일 단계에서 잡는게 불가능했다.
List<Tv> list2 = new ArrayList<>();
list2.add(new Tv());
Tv tv1 = list2.get(0);
List list3 = new ArrayList<>(); //생성시 지네릭스타입을 선언해주지 않을경우
list3.add(new Tv());
Tv tv2 = (Tv) list3.get(0); // 형변환을 해줘야 하는 번거로움이 생긴다.
}
}
class Tv {
}
class Audio {
}
package JavaJungSuk3_Study.Example.java8;
import java.util.ArrayList;
import java.util.List;
public class GenericsExample_2 {
public static void main(String[] args) {
List<Tv2> list = new ArrayList<>();
list.add(new Tv2());
list.get(0).setPassive("passive");
System.out.println(list.get(0).getPassive());
}
}
class Tv2<T> { //이런식으로 대입이가능 object를 모두 t로 바꾼다
T passive;
public T getPassive() {
return passive;
}
public void setPassive(T passive) {
this.passive = passive;
}
}
class Audio2<E> { //이런식으로 대입이가능 object를 모두 t로 바꾼다
E passive;
public E getPassive() {
return passive;
}
public void setPassive(E passive) {
this.passive = passive;
}
}
ArrayList<Tv> tvList = new ArrayList<Tv>();
이런식으로 사용자가 Tv 뿐아니라 다양한 타입을 사용 가능 하도록 한다.
지네릭스 도입 이후 자바의 많은 클래스들이 클래스<T>
식으로 변화 되었다. 결론적으로는 지네릭스 도입 이후로 불필요한 형변환, 컴파일 단계에서 타입 에러를 잡는 것이 가능해졌다.
public class ArrayList<E> extends AbstractList<E>
ArrayList의 class 시작 부분인데 <E>가 Tv2로 바뀐다 즉 생성 할때마다 다른타입을 넣어줄수있다.
T[] tv;
이런식으로 변수의 타입을 지네릭스로 사용한는 거은 허용되지만 T[] tv = new T[];
는 불가하다. 컴파일 단계에서 타입 T가 무엇인지 명확히 알지 못하기 때문.public class FruitBox<T extends Fruit> extends Box {}
원래는 FruitBox에 모든 타입 지네릭 타입이 들어 올 수 있었지만 이와같이 Fruit과 자손들만 가능 하도록 할 수 있다. package JavaJungSuk3_Study.Example.ch12;
import java.util.ArrayList;
interface Eatable {
}
class Fruit implements Eatable {
public String toString() {
return "Fruit";
}
}
class Apple extends Fruit {
public String toString() {
return "Apple";
}
}
class Grape extends Fruit {
public String toString() {
return "Grape";
}
}
class Toy {
public String toString() {
return "Toy";
}
}
public class FruitBoxEx1 {
public static void main(String[] args) {
FruitBox<Fruit> fruitBox = new FruitBox<>();
FruitBox<Apple> appleFruitBox = new FruitBox<>();
FruitBox<Grape> grapeFruitBox = new FruitBox<>();
Box<Fruit> fruitBox1 = new Box<Fruit>();
Box<Apple> appletBox = new Box<Apple>();
Box<Toy> toyBox = new Box<Toy>();
fruitBox.add(new Fruit());
fruitBox.add(new Apple());
fruitBox.add(new Grape());
appletBox.add(new Apple());
appletBox.add(new Fruit());// 타입불일치
appletBox.add(new Grape());// 타입불일치
}
}
class FruitBox<T extends Fruit & Eatable> extends Box<T> { // 타입은 Fruit 와 Eatable을 구현,상속받은 경우만 가능
}
class Box<T> {
ArrayList<T> list = new ArrayList<T>();
void add(T item) {
list.add(item);
}
T get(int i) {
return list.get(i);
}
int size() {
return list.size();
}
public String toString() {
return list.toString();
}
}
class FruitBox<T extends Fruit & Eatable> extends Box<T>
public void set(T value){}
위클래스에 set메서드가 있을경우FruitBox<Fruit> fruitBox = new FruitBox<>(); fruitBox.set("멍멍");
//컴파일 에러 FruitBox<Fruit> fruitBox1 = new FruitBox<Fruit>();
// FruitBox<Fruit> fruitBox2 = new FruitBox<Apple>(); // 지네릭 타입을 맞춰 줘야한다.
FruitBox<? extends Fruit> fruitBox3 = new FruitBox<Fruit>(); // 와일드 카드를 쓰면 가능해진다 //Fruit와 그의자손들
fruitBox3 = new FruitBox<Apple>();
fruitBox3 = new FruitBox<Grape>();
fruitBox3 = new FruitBox<Fruit>();