자바 범용 지우 기
The Java™ Tutorials http://www.baeldung.com/java-type-erasure
범용 지우 기
Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.
만약 에 범 형 매개 변수 가 경계 가 있다 면 컴 파일 한 후에 경계 로 바 뀔 것 입 니 다. 그렇지 않 으 면
Object
로 바 뀔 것 입 니 다. 필요 한 전환 작업 을 삽입 합 니 다. 범 형 류 를 계승 하 는 클래스 에 있어 컴 파일 러 는 브리지 방법 bridge methods
을 추가 하여 다 중 태 를 유지 할 것 입 니 다. 컴 파일 한 후에 새로운 클래스 가 생 성 되 지 않 았 기 때문에 범 형 운행 시 추가 비용 을 도입 하지 않 았 습 니 다.예시
During the type erasure process, the Java compiler erases all type parameters and replaces each with its first bound if the type parameter is bounded, or Object if the type parameter is unbounded.
위의
replaces each with its first bound
는 아직 연구 가 필요 합 니 다. 개인 적 인 이 해 는
이러한 상황 에서 일반적인 유형 이 First
로 바 뀌 었 다 는 것 입 니 다. 클 라 스 파일 을 역 컴 파일 하여 검증 하려 고 했 는데 Java1.8
컴 파일 된 클 라 스 파일 을 역 컴 파일 한 후에 범 형 매개 변 수 를 보 았 습 니 다. 아이디어 자체 의 역 컴 파일 도 구 를 사용 하여 클 라 스 파일 을 역 컴 파일 하 는 것 에 대해 서 는...범 형 유형의 원인 을 볼 수 있 습 니 다. 다음 과 같은 몇 편의 글 을 참고 할 수 있 습 니 다. 이 글 을 잘 썼 는 지 아 시 겠 습 니까? 추천 합 니 다. 자바 범 형 지우 기 는 어느 단계 에서 발생 하 는 지, 어떻게 반 컴 파일 도구 로 범 형 지우 기 후의 코드 를 볼 수 있 습 니까?java - generic - types - type - erasure java - type - erasure - Why - can - i - see - the - type - when - i - look - at - the - bytecode. 문장 은 마지막 으로 몇 개의 역 컴 파일 된 예 를 썼 습 니 다. 본문 마지막 에 볼 수 있 습 니 다.무한 범 형 매개 변수
public class Node {
private T data;
private Node next;
public Node(T data, Node next) {
this.data = data;
this.next = next;
}
public T getData() { return data; }
// ...
}
무한 이기 때문에 유형 매개 변 수 는 직접
Object
로 바 뀌 었 습 니 다. 컴 파일 후:public class Node {
private Object data;
private Node next;
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public Object getData() { return data; }
// ...
}
유 계 범 형 매개 변수
public class Node> {
private T data;
private Node next;
public Node(T data, Node next) {
this.data = data;
this.next = next;
}
public T getData() { return data; }
// ...
}
한 정 된 경계 가 있 기 때문에 바로
Comparable
로 바 뀌 었 습 니 다. 코드 는 다음 과 같 습 니 다.public class Node {
private Comparable data;
private Node next;
public Node(Comparable data, Node next) {
this.data = data;
this.next = next;
}
public Comparable getData() { return data; }
// ...
}
일반적인 방법의 유형 지우 기
무한 하 다
// Counts the number of occurrences of elem in anArray.
//
public static int count(T[] anArray, T elem) {
int cnt = 0;
for (T e : anArray)
if (e.equals(elem))
++cnt;
return cnt;
}
컴 파일 후:
public static int count(Object[] anArray, Object elem) {
int cnt = 0;
for (Object e : anArray)
if (e.equals(elem))
++cnt;
return cnt;
}
경계 가 있다
class Shape { /* ... */ }
class Circle extends Shape { /* ... */ }
class Rectangle extends Shape { /* ... */ }
일반적인 방법:
public static void draw(T shape) { /* ... */ }
컴 파일 후:
public static void draw(Shape shape) { /* ... */ }
유형 지우 기 영향 및 브리지 방법
다음 두 가 지 를 고려 하 다
public class Node {
public T data;
public Node(T data) { this.data = data; }
public void setData(T data) {
System.out.println("Node.setData");
this.data = data;
}
}
범 형 류 에 계승:
public class MyNode extends Node {
public MyNode(Integer data) { super(data); }
public void setData(Integer data) {
System.out.println("MyNode.setData");
super.setData(data);
}
}
호출 상황:
MyNode mn = new MyNode(5);
Node n = mn; // A raw type - compiler throws an unchecked warning
n.setData("Hello");
Integer x = mn.data; // Causes a ClassCastException to be thrown.
형식 지우 기 후의 코드:
MyNode mn = new MyNode(5);
Node n = (MyNode)mn; // A raw type - compiler throws an unchecked warning
n.setData("Hello");
Integer x = (String)mn.data; // Causes a ClassCastException to be thrown.
해석:
브리지 방법
유형 을 지 운 후에 위의 두 가지 유형 은 다음 과 같은 형식 으로 변 한다.
public class Node {
public Object data;
public Node(Object data) { this.data = data; }
public void setData(Object data) {
System.out.println("Node.setData");
this.data = data;
}
}
public class MyNode extends Node {
public MyNode(Integer data) { super(data); }
public void setData(Integer data) {
System.out.println("MyNode.setData");
super.setData(data);
}
}
두 가지 방법
setData
을 볼 수 있 습 니 다. 사실은 Override
의 요 구 를 만족 시 키 지 못 합 니 다. 매개 변수 유형 이 다 르 기 때 문 입 니 다. 이 문 제 를 해결 하기 위해 컴 파일 러 는 브리지 방법 을 만들어 다 형 을 유지 합 니 다.class MyNode extends Node {
// Bridge method generated by the compiler
//
public void setData(Object data) {
setData((Integer) data);
}
public void setData(Integer data) {
System.out.println("MyNode.setData");
super.setData(data);
}
// ...
}
javap 역 컴 파일 을 사용 하여 일반적인 형식 지우 기 예 를 봅 니 다.
아래 이 단락 에 대한 검증.
During the type erasure process, the Java compiler erases all type parameters and replace each with its first bound if the type parameter is bounded. 두 개의 인터페이스
A
와 B
:package generictopic.typeerasure;
/**
* Created by xiaofu on 17-11-7.
*/
public interface A {
void a();
}
package generictopic.typeerasure;
/**
* Created by xiaofu on 17-11-7.
*/
public interface B {
void B();
}
클래스
FirstBoundA
, 실현 A
과 B
인터페이스, 그리고 A
앞 에 쓰기:package generictopic.typeerasure;
/**
* Created by xiaofu on 17-11-7.
*/
public class FirstBoundA {
public void test(T item){
System.out.println(item);
}
}
클래스
FirstBoundB
, 실현 A
과 B
인터페이스, 그리고 B
앞 에 쓰기:package generictopic.typeerasure;
/**
* Created by xiaofu on 17-11-7.
*/
public class FirstBoundB {
public void test(T item){
System.out.println(item);
}
}
이 몇 개의 파일 을 컴 파일 한 다음 에 각각
javap
으로 역 컴 파일 합 니 다. 자바 p 인 자 는 간단 하기 위해 -s
인 자 를 직접 사용 합 니 다. 즉 Prints internal type signatures.
대 FirstBoundA.class
에 대해 역 컴 파일 작업 을 수행 합 니 다.javap -s FirstBoundA.class
test
방법 을 볼 수 있 습 니 다. descriptor
부분 은 Lgenerictopic/typeerasure/A;
, 즉 범 형 유형 이 첫 번 째 경계 A
로 바 뀌 었 습 니 다.Compiled from "FirstBoundA.java"
public class generictopic.typeerasure.FirstBoundA {
public generictopic.typeerasure.FirstBoundA();
descriptor: ()V
public void test(T);
descriptor: (Lgenerictopic/typeerasure/A;)V
}
다시
FirstBoundB.class
에 대한 역 컴 파일 결 과 를 볼 수 있 습 니 다. 매개 변 수 는 첫 번 째 경계 B
로 바 뀌 었 습 니 다.Compiled from "FirstBoundB.java"
public class generictopic.typeerasure.FirstBoundB {
public generictopic.typeerasure.FirstBoundB();
descriptor: ()V
public void test(T);
descriptor: (Lgenerictopic/typeerasure/B;)V
}
따라서 특정한 범 형 매개 변수 가 여러 개의 경계 가 있 을 때 컴 파일 러 의 방법 은 유형 을 첫 번 째 경계 로 바 꾸 는 것 이다. 그러나 이 유형의 매개 변 수 는 여러 개의 경계 가 있 고 그 중 하 나 는
class
이 라면 반드시 첫 번 째 에 써 야 한다. 이것 은 문법 이 요구 하 는 것 이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.