>  기사  >  Java  >  Java Generics 시작하기 분석

Java Generics 시작하기 분석

WBOY
WBOY앞으로
2023-04-29 21:19:121466검색

1. 제네릭은 실제로 유형을 매개변수로 전달합니다. 제네릭을 사용하면 프로그래머는 나중에 코드를 작성할 때 특정 유형을 사용하여 클래스를 인스턴스화할 수 있습니다. 유형.

제네릭을 도입하는 이유는 무엇인가요?

예: 직접 시퀀스 테이블 구현

public class MyArrayList {
    public int[] elem;
    public int usedSize;

    public MyArrayList() {
        this.elem = new int[10];
    }
    // add方法
    public void add(int val) {
        // 暂时不考虑扩容问题,这里只是为了讲泛型
        elem[usedSize++] = val;
    }
    // get方法
    public int get(int pos) {
        return elem[pos];
    }
}

위의 사용자 정의 시퀀스 테이블을 사용할 때 int 유형 요소만 추가할 수 있다는 것을 여기서 볼 수 있습니다. Java 컬렉션의 시퀀스 테이블은 모든 유형을 추가할 수 있다는 것을 알고 있습니다. 데이터는 어떻게 얻어지나요? 여기서는 먼저 int 유형을 Object 유형으로 변경하여 모든 유형이 전달될 수 있도록 보장합니다.

public class MyArrayList {
    public Object[] elem;
    public int usedSize;

    public MyArrayList() {
        this.elem = new Object[10];
    }
    // add方法
    public void add(Object val) {
        // 暂时不考虑扩容问题,这里只是为了讲泛型
        elem[usedSize++] = val;
    }
    // get方法
    public Object get(int pos) {
        return elem[pos];
    }
}

메인 메소드에서 객체에 데이터를 추가할 때 어떤 유형의 데이터라도 추가할 수 있습니다. 하지만 데이터를 꺼내야 할 경우 반환되는 타입이 Object이기 때문에 해당 타입으로 받기 위해서는 강제 변환이 필요하므로 매우 번거롭다.

public static void main(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(1);
        myArrayList.add("hello");
        int array1 = (int)myArrayList.get(0);
        String array2 = (String)myArrayList.get(1);
    }

그러니까, 받기 전에 매번 강제로 전송해야 하는 건가요? 강제로 전송하면 안 되나요? 이때 우리는 인스턴스 객체를 생성할 때 원하는 유형을 매개변수로 전달하면 전달된 유형의 모든 데이터가 이 객체에 저장될 수 있다고 생각했습니다. 그러면 이를 꺼낼 때 명확하게 식별할 수 있습니다. 개체의 모든 데이터는 모두 이 유형이므로 강제로 전송할 필요가 없습니다. 이것은 제네릭을 소개합니다.

public class MyArrayList<E> {
	// 在编写程序时,不指定具体的类型,而用<E>这里的E来暂时代替
    // 具体的类型在实例化对象时传入
    public E[] elem;
    public int usedSize;

    public MyArrayList() {
    	// 这里的写法不是特别准确,应该用反射机制,这里先这样写
        this.elem = (E[])new Object[10];
    }
    // add方法
    public void add(E val) {
        // 暂时不考虑扩容问题,这里只是为了讲泛型
        elem[usedSize++] = val;
    }
    // get方法
    public E get(int pos) {
        return elem[pos];
    }
}
public static void main(String[] args) {

        MyArrayList<Integer> myArrayList1 = new MyArrayList<>();
        myArrayList1.add(1);
        myArrayList1.add(3);
        // myArrayList1.add("world");// 这里会报错,因为传入的数据不是指定的类型,所以泛型还有自动对类型进行检查的作用
        int I1 = myArrayList1.get(0);
        
        MyArrayList<String> myArrayList2 = new MyArrayList<>();
        myArrayList2.add("hello");
        myArrayList2.add("world");
        String s1 = myArrayList2.get(0);
    }

이렇게 하면 모든 유형의 데이터를 전달할 수 있으며 데이터를 꺼낼 때 강제로 전송할 필요가 없습니다! 제네릭의 의미:

1. 자동으로 유형을 확인합니다

2. 유형에 대해 자동으로 유형 변환을 수행합니다.

여기서 MyArrayList의 해당 객체 유형은 무엇입니까? MyArrayList

Java Generics 시작하기 분석여기에서 인스턴스에 의해 생성된 객체의 유형은 모두 MyArrayList이고 의 콘텐츠는 일반 유형의 구성에 참여하지 않으므로 ;? 이를 위해서는 제네릭의 작동 메커니즘을 이해해야 합니다.

2. 제네릭 컴파일 방법

배열과 제네릭의 중요한 차이점은 유형 검사를 적용하는 방법입니다. 특히 배열은 런타임에 유형 정보를 저장하고 확인합니다. 그러나 제네릭은 컴파일 타임에 유형 오류를 확인하고 런타임에는 유형 정보가 없습니다.

일반 컴파일 메커니즘: 삭제 메커니즘

컴파일 중에 MyArrayList의 E가 개체 유형으로 지워집니다.

Java Generics 시작하기 분석은 모두 기본 메소드에서 MyArrayList 유형으로 변경됩니다.

위 내용은 Java Generics 시작하기 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제