Как вы справляетесь с "супер" дженериками в Java? - PullRequest
5 голосов
/ 22 октября 2008

Возьмите следующий пример дженериков

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

public class GenericsTest {
    private List<Animal> myList;

    public static void main(String args[]) {
        new GenericsTest(new ArrayList<Animal>()).add(new Dog());
    }

    public GenericsTest(List<Animal> list) {
        myList = list;
    }

    public void add(Animal a) {
      myList.add(a);
    }

    public interface Animal {}
    public static class Dog implements Animal {}
    public static class Cat implements Animal {}
}

Работает нормально. Но, как вы знаете, вы не можете построить это с

new GenericsTest(new ArrayList<Dog>());

потому что, как вы знаете, add (Animal) позволит добавить Cat s. предлагаемый способ решения этой проблемы, то есть подстановочные знаки тоже не работают, потому что, да, вы можете изменить каждый List<Animal> в List<? extends Animal>, но у него та же проблема: вы можете создать GenericsTest с List<Cat> и затем добавьте Dog с.

Итак, мой вопрос: есть ли удобный способ написать этот класс один раз, а затем использовать его для всех возможных Animals? Конечно, это должно прямо решить вышеупомянутую проблему.

Ответы [ 2 ]

6 голосов
/ 22 октября 2008

Если я понимаю, что вы пытаетесь сделать, вам нужно поместить универсальный тип на уровень класса:

public class GenericsTest<T extends Animal>
{
  private List<T> myList;

  public static void main(String args[])
  {
    new GenericsTest<Dog>(new ArrayList<Dog>());
  }

  public GenericsTest(List<T> list)
  {
    myList = list;
  }

  public void add(T a)
  {
    myList.add(a);
  }
}
2 голосов
/ 22 октября 2008

Возможно, вы захотите сделать класс целом общим, а не только параметры:

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

public class GenericsTest<T extends Animal> {
    private final List<T> myList;

    public static void main(final String args[]) {
        new GenericsTest<Animal>(new ArrayList<Animal>()).add(new Dog());
        new GenericsTest<Dog>(new ArrayList<Dog>()).add(new Dog());
        new GenericsTest<Cat>(new ArrayList<Cat>()).add(new Cat());
    }

    public GenericsTest(final List<T> list) {
        myList = list;
    }

    public void add(final T a) {
      myList.add(a);
    }
}

// Can't nest as Animal needs to be in scope of class declaration
interface Animal {}
class Dog implements Animal {}
class Cat implements Animal {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...