Рубрики
Без рубрики

Введение в подстановочные знаки Java

Введение Подстановочный знак (?) может помочь нам написать программу более понятным способом. Оно… Помеченный java.

Вступление

Подстановочный знак ( ? ) может помочь нам написать программу более понятным способом.

Он используется для представления неизвестного типа и никогда не используется в качестве аргумента типа для вызова универсального метода, создания экземпляра универсального класса или супертипа.

Пример

Давайте предположим, что у нас есть иерархия объектов:

  • Класс Animal наследуется от Объект тривиально
  • Классы Собака и Кошка наследуются от Животного
  • Класс Золотистый ретривер наследуется от Собаки

В общем, есть 3 способа использовать подстановочный знак:

  • Верхняя граница: пустое удовольствие(Список расширяет список животных>) Этот список входных данных параметризован по не более типа Животное (может быть любым подтипом Животного )

  • Нижняя граница: пустое удовольствие(Список супер Животное> список) Этот список входных данных параметризован по по крайней мере тип Животное (может быть любым супертипом Животного )

  • Неограниченный: пустое веселье(список список) {список.очистить();}

    • Здесь нам все равно, какой тип списка, так как clear() не зависит от типа.
    • Если бы мы должны были использовать только методы, определенные в Объект , то неограниченный подстановочный знак работает нормально.

Демонстрационный код Java

Смотрите следующий код, WildcardDemo.java , для лучшего понимания.

Сначала попробуйте скомпилировать его с помощью javac WildcardDemo.java и увидеть консоль ошибок:)

Во-вторых, чтобы успешно скомпилировать код, обратите внимание, что есть 2 строки, помеченные как //X (не удается скомпилировать) , вы должны прокомментировать их, чтобы скомпилировать код.

Код полностью прокомментирован. Не стесняйтесь оставлять любые комментарии, если вы не понимаете.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Our Object Hierarchy:
 *
 *          Object
 *            |
 *          Animal
 *           / \
 *        Dog   Cat
 *         |
 *  GoldenRetriever
 */
public class WildcardDemo {

  private class Animal {}
  private class Dog extends Animal {}
  private class Cat extends Animal {}
  private class GoldenRetriever extends Dog {}

  // `animals` is parameterized over "at most" type `Animal`
  private void funExtends(List animals) {
    // Can't add a Dog (subtype) to the `animals` because it may
    // contain something "lower than an Animal".
    // For example, it might be `List` or `List`
    animals.add(new Dog()); // X (can't compiled)

    // Can't put anything into a type declared with an extends
    // wildcard except for the value `null`, which is a subtype
    // of every reference type
    animals.add(null);

    // Can retrieve an `Animal`, because any subtype of `Animal`
    // must be an `Animal`
    Animal animal = animals.get(0);

    System.out.println(animal.getClass().toString());
  }

  // `animals` is parameterized over "at least" type `Animal`
  private void funSuper(List animals) {
    // Can add a `Dog` (subtype) to the `animals` because a `Dog`
    // is guaranteed an `Animal` or any supertype of an `Animal`
    animals.add(new Dog());

    // Can't get anything out from a type declared with a super
    // wildcard except for a value of type `Object`, which is a
    // super type of every reference type
    Animal animal = animals.get(0); // X (can't compiled)
    Object object = animals.get(1);

    System.out.println(object.getClass().toString());
  }

  private List getAnimals() {
    return new ArrayList<>(Arrays.asList(
        new GoldenRetriever(),
        new Cat()
      )
    );
  }

  public static void main(String[] args) {
    WildcardDemo demo = new WildcardDemo();
    List animals = demo.getAnimals();
    demo.funExtends(animals);
    demo.funSuper(animals);
  }
}

Оригинал: “https://dev.to/walkccc/java-wildcards-demo-554f”