>  기사  >  Java  >  12.Java 기본 - 와일드카드

12.Java 기본 - 와일드카드

黄舟
黄舟원래의
2017-02-27 10:46:041356검색


기본 개념


물음표를 사용하여 유형 매개변수를 나타내는 와일드카드는 메소드 [알 수 없는 유형]의 [유형 제약 조건]을 나타냅니다.

제네릭은 데이터 유형을 매개변수로 정의하며, 사용 시 특정 유형을 지정할 수 있습니다. 그러나 특정 유형을 사용할 때 결정할 수 없는 경우 와일드카드를 사용하여 이를 해결해야 합니다.

추상적으로 말하면 제네릭은 공분산을 지원하지 않기 때문에 제네릭 유형을 공분산으로 만들기 위해 와일드카드가 도입되었습니다.


와일드카드의 역할

다음에서는 두 가지 예를 사용하여 와일드카드의 역할을 살펴봅니다.

1. 와일드카드를 사용하지 마세요.

ArrayList<Object> list_obj = null;
ArrayList<String> list_str = new ArrayList<String>();
// ArrayList 的元素支持  String -> Object 的强制转换list_str.add("hello");
System.out.println((Object)list_str.get(0));// 编译错误,泛型不支持协变list_obj = list_str;

코드를 관찰한 결과 다음이 발견되었습니다.

  • ArrayList에 저장된 요소는 다음과 같습니다. String은 Object의 하위 클래스이기 때문에 String ->에서 Upcast를 지원합니다.

  • ArrayList의 매개변수 유형이 String -> Object에서 변환될 때 컴파일 오류가 발생했습니다. 제네릭은 공분산을 지원하지 않기 때문입니다.


2. 와일드카드 문자

ArrayList<String> list_str = new ArrayList<String>();
list_str.add("hello");

ArrayList<Integer> list_int = new ArrayList<Integer>();
list_int.add(100);

ArrayList<?> list = null;
list = list_str;
System.out.println(list.get(0));    // hellolist = list_int;
System.out.println(list.get(0));    // 100//编译错误list.add("hello");
list.add(100);

를 사용하여 코드를 관찰하고 다음을 찾습니다.

  • 와일드카드를 사용한 후에는 모든 유형의 변환을 허용하여 제네릭이 공분산을 지원하지 않는다는 제한 사항을 해결합니다.

  • 그러나 모든 유형의 개체를 추가할 수 있는 권한도 상실됩니다.


와일드카드 유형

와일드카드에는 세 가지 형태가 있습니다. 즉,

//1、无限定通配符 Demo<?>//2、上边界限定通配符 Demo< ? extends Number>   

//3、下边界限定通配符    Demo< ? super Number>

1. 상한 와일드카드

다음 예를 살펴보세요. 상속 관계가 있는 세 개의 클래스, 즉 Person ->

class Person{    void print(){
    }
}

class Man extends Person{    void paly(){
    }
}

class Worker extends Man{    void say(){
    }
}public class Test {
    public static void main(String[] args)  {        
    // 创建了三个 ArrayList 数组
        ArrayList<Person> personList = new ArrayList<Person>();
        ArrayList<Man> manList= new ArrayList<Man>();
        ArrayList<Worker> workerList = new ArrayList<Worker>();        
        // 限定了上界, ? 代表 Man 以及继承 Man 的类
        ArrayList<? extends Man> list  = null;

        list = manList;
        list = workerList;        // 编译错误,因为 Person 是 Man 的父类
        list = personList;        // 编译错误,因为使用了通配符就不能添加对象
        list.add(new Man());
        list.add(new Worker());        for(Man man : list){
            man.print();
            man.paly();
        }        for(Person per : list){
            per.print();
        }        // 编译错误,因为 ? 也可以代表 Man
        // 从继承我们可以知道 Worker 肯定是 Man,但 Man 不一定是 Worker。
        // for(Worker worker : list);
    }
}

2. 하한 와일드카드

// 省略相同代码...public class Test {
    public static void main(String[] args)  {
        ArrayList<Person> personList = new ArrayList<Person>();
        ArrayList<Man> manList= new ArrayList<Man>();
        ArrayList<Worker> workList = new ArrayList<Worker>();        
        // 限定了下届, ? 代表 Man 以及 Man 的父类
        ArrayList<? super Man> list  = null;

        list = personList;
        list = manList;        // 编译错误,因为 Worker 是 Man 的子类
        list = workList;        // 编译错误,无法确定其父类对象
        // Person 继承子 Cell 类,那么用 Person 遍历就是错误的
        // for(Man man : list);
        // for(Person per : list);

        // 因为 Object 是所有类的根类,所以可以用Object来遍历
        // for(Object obj : list);
    }
}

3. 무제한 와일드카드

// 省略相同代码...public class Test {
    public static void main(String[] args)  {
        ArrayList<Person> personList = new ArrayList<Person>();
        ArrayList<Man> manList= new ArrayList<Man>();
        ArrayList<Worker> workList = new ArrayList<Worker>();        //无边界通配符
        ArrayList<?> list  = null;        //可以代表一切类型
        list = personList;
        list = manList;
        list = workList;        //为了避免类型混淆,只允许使用 Object 遍历
        for(Object obj : list); 
    }
}

12.Java Basics - Wildcards 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.