범용-[OOP&Java#5]
지난 글에서 나는 물건을 소장품에 넣는 필요성에 대해 이야기했다.Python에서는 목록에 정수, 문자열 등을 저장합니다. 자바에서는 기본 모듈이 형식에 따라 특정한 유형의 대상을 저장합니다.
int[] arrayOfInts = new int[2];
String[] arrayOfStrings = new String[2];
그때 파이톤에서 정수와 문자열을 같은 용기에 자유롭게 넣을 수 있을 것 같다고 말했다.나는 또 다른 자유도를 놓쳤다.컨테이너의 컨텐트 유형을 동일하게 유지하면서 Python에서 먼저 일반 목록을 만든 다음 정수 목록으로 사용할지 문자열 목록으로 사용할지 결정할 수 있습니다.Java에서 기본 배열은 유형 선언으로 작성되며 이후에 변경되지 않습니다.이것이 바로 우리가 모조약을 필요로 하는 이유다.진화하다
서랍이 하나 있다고 가정해 봐.서랍 안에 많은 물건을 넣을 수 있다.조리가 없는 사람으로서 서랍에 라벨을 붙여서 특정한 물품만을 겨냥하고 싶지 않다(한 서랍은 옷을 넣고, 다른 서랍은 서류를 넣는 등).Java에서는 컴파일할 때 유형을 선언해야 하기 때문에 다음 방법을 사용할 수 있습니다.
A drawer can contain an Object.
class Drawer {
Object obj;
Drawer(Object obj) {
this.obj = obj;
}
Object get() {
return this.obj;
}
}
이제 서랍을 만들 수 있습니다. 컴파일러가 서랍에 무엇을 넣었는지 신경 쓰지 않는 것 같습니다.// store a shirt into the drawer
Drawer drawer = new Drawer("shirt");
// store integers into the drawer
Drawer drawer = new Drawer(123);
drawer.get() // returns an "Object"
서랍에서 물건을 어떻게 꺼내요?현재 서랍에 저장된 모든 물건은 Object
유형이 될 것이다.서랍에서 물건을 꺼낼 때마다 유형 전환을 책임져야 한다.Java에서는 컴파일할 때 최소한 런타임 전에 객체가 할 수 있는 작업을 결정합니다.이것은 서랍에서 꺼낸 대상에 대한 어떤 방법도 유형과 호환되어야 한다는 것을 의미한다.만약 항목의 유형이
Object
이라면 컴파일러는 Object
급의 조작만 안전하게 실행할 수 있다. 예를 들어 toString()
.Drawer drawer = new Drawer("shirt");
Drawer drawer = new Drawer(123);
// ERROR: incompatible types: .. Object cannot be converted to String
String shirt = drawer.get();
// Error: ClassCastException Integer cannot be String
String shirt = (String)drawer.get();
Drawer drawer = new Drawer("shirt");
// SAFE: type cast Object to String before assignment
String shirt = (String)drawer.get();
이상에서 두 문제를 설명하였다.cannot find symbol
오류가 발생할 수 있습니다.이것은 컴파일러가 말한 "나는 이런 방법이 이런 유형의 대상에 적용될 줄 몰랐다."// ERROR: what I get out is an Object, which does not
// have a 'length()' method
new Drawer("string").get().length()
// ERROR: order of casting is wrong
(String)(new Drawer("string").get()).length()
// SAFE
((String)new Drawer("string").get()).length()
이런 방법은 서투르고 잘못되기 쉬워서 서랍에서 물건을 꺼낼 때마다 목적지에서 타자를 쳐야 한다.모조약의 탄생
위 예에서 언급한 문제 및 요구 사항을 해결하기 위해 다음을 수행합니다.
Terminology: type parameters and type arguments
// the "T" and "U" below are type parameters
// generic class declaration
class Car<T> {}
// generic method declaration
public static <U> void doThis(U item) {}
// The "String" below is a type argument
new Car<String>();
범형으로 서랍을 재정의하다class Drawer<T> {
T obj;
Drawer(T obj) {
this.obj = obj;
}
T get() {
return this.obj;
}
}
위의 클래스 정의에서 우리는 T
에서 <>
를 정의했는데 이것은 우리가'자리 차지 문자'를 정의했다는 것을 의미한다.알파벳 'T' 는 매우 간단합니다. 'U', 'O' 등 다른 문자열로 변경할 수 있습니다. 이런 의미에서 'T' 는 변수로 볼 수 있으며, 나중에 지정할 유형을 저장할 수 있습니다.자리 표시자가 여러 개 있을 수 있습니다.Java의 일반 유형 매개변수 이름
성함
뜻
E
원소.
K
열쇠.
다섯
가치관
N
번호
T
타입
현재 검색 대상은 매우 쉽다.
// PREVIOUSLY
Drawer drawer = new Drawer("string");
((String)drawer.get()).length()
// CURRENT
Drawer<String> drawer = new Drawer<String>("string");
drawer.get().length()
클래스 정의 중의 유형 매개 변수의 사상에 따라 우리는 방법에 대해 같은 조작을 집행할 수 있다.// type parameter | return type | method name | method arguments
<U> Drawer<U> customDrawer(U obj) {
return new Drawer<U>(obj);
}
범용 방법에 대해 유형 매개 변수의 작용역은 방법 자체이다.만약 이 방법이 일반 클래스에 있다면, 이 방법의 유형 매개 변수는 이 클래스의 유형 매개 변수와 무관하다.우리도 범형 방법을 범형류에 넣을 수 있다.다시 한 번 주의하지만, 이 두 종류의 매개 변수는 서로 다른 범위 내에 있다.
class Drawer<T> {
T obj;
Drawer(T obj) {
this.obj = obj;
}
T get() {
return this.obj;
}
static <U> Drawer<U> customDrawer(U u) {
return new Drawer<U>(u);
}
}
// calling the static method like this
Drawer<Integer> drawer = Drawer.customDrawer(123);
drawer.get() // outputs 123
자동 포장 및 분리
일반적으로 자바가 원시 데이터 형식을 인용 형식으로 자동으로 처리하는 방법에 대한 토론은 자바 과정의 초기에 소개되었다.모조약은 이 개념을 재검토했다.
// ERROR, does not accept primitive types
Drawer<int> drawer = new Drawer<int>(123);
// auto-boxing
Drawer<Interger> drawer = new Drawer<Integer>(123);
// retrieve the Integer within the drawer
Integer x = drawer.get();
// auto-unboxing
int x = drawer.get();
유형 차이
협방차
역변했어
변하지 않았어
하위 유형 관계
보존
거꾸로 했어
보류도 역전도 없다
이런 전문 어휘를 두려워하지 말고 예를 들어 봅시다.
협방차
A subclass relationship can be extended to complex data types such as Array.
// since Integer is a subtype/subclass of Object
Object o = new Integer(123);
// this relationship is preserved in Java arrays
Object[] arr = new int[1];
역변했어The opposite of Covariance. Will be addressed in details when we discuss wildcards in the following article 😂
변하지 않았어
// ERROR
Drawer<Object> drawer = new Drawer<Integer>(123);
// SAFE
Drawer<Integer> drawer = new Drawer<Integer>(123);
범형은 변하지 않는다.따라서 등호의 왼쪽과 오른쪽에서 대체되는 유형 매개 변수는 항상 같아야 한다.따라서 우리는 오른쪽Integer
을 생략할 수 있다.Drawer<Integer> drawer = new Drawer<>(123);
자바는 정확한 유형을 추정할 수 있습니다.다음은 와일드카드💨
복제약에 관한 NUS CS2030S 강좌를 참고하여 작성한 부언
Reference
이 문제에 관하여(범용-[OOP&Java#5]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/tlylt/generics-oop-java-5-2k46텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)