Кастинг - foreach - Ява - PullRequest
       9

Кастинг - foreach - Ява

2 голосов
/ 17 июня 2011

У меня есть один метод, подобный этому:

private void myMethod(List<?> myLists) {

   for (Object val : myLists) {
       val.getMyOtherMethod(); // for example
   }

}

Как я могу привести val к одному из моих объектов?

Все мои объекты (списковые объекты) содержат те же методы, что и getMyOtherMethod()

BR

edit: ---------------------------------------------------------------------

Я звонил myMethod несколько раз, например:

List<MyClas.MySubclass1> var1;
List<MyClas.MySubclass2> var1;
List<MyClas.MySubclass3> var1;
...
...

myMethod(var1);
myMethod(var2);
myMethod(var3);

В этом случае я не знаю, подкласс ведьмы я отправляю MySubclass1, MySubclass2 или MySubclass3.Это важно для цикла foreach.

Ответы [ 6 ]

11 голосов
/ 17 июня 2011

Вам необходим список элементов, которые реализуют getMyOtherMethod ()

interface ImplementsGetMyOtherMethod {
   void getMyOtherMethod();
}

private void myMethod(List<? extends ImplementsGetMyOtherMethod> myLists) {
3 голосов
/ 17 июня 2011

Вы можете приводить только к типу, который есть у ваших объектов. Наличие правильного метода здесь недостаточно. Если у вас есть разные классы, у которых у всех один и тот же метод, позвольте им реализовать интерфейс, который также предоставляет метод.

Тогда вы можете сделать

for (Object val : myLists) {
   ((MyInterface) val).getMyOtherMethod();
}

или (если у вас несколько методов):

for (Object val : myLists) {
   MyInterface mi = (MyInterface) val;
   mi.getMyOtherMethod();
   mi.doSomething();
}

Конечно, тогда вы обычно будете использовать List<MyInterface> вместо List<?> и вообще избегать приведения.

2 голосов
/ 17 июня 2011

Правильный способ решить эту проблему - использовать обобщенные элементы для принудительной проверки типов во время компиляции. Если все объекты реализуют общий интерфейс

interface IFoo {
    Bar getMyOtherMethod();
}

тогда myMethod должно занять List<IFoo>, а не List<?>:

private void myMethod(List<IFoo> myLists)
{
   for (IFoo val : myLists)
   {
       val.getMyOtherMethod();
   }
}

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

2 голосов
/ 17 июня 2011

Определить / использовать интерфейс, который все они реализуют:

interface HasMyOtherMethod {
    void getMyOtherMethod();
}

private <T extends HasMyOtherMethod> void myMethod(List<T> myLists) {
   for (T val : myLists) {
       val.getMyOtherMethod();
   }
}

РЕДАКТИРОВАНИЕ: Добавлена ​​общая верхняя граница: Будет работать любой подкласс HasMyOtherMethod.

Преимуществоэто преувеличение заключается в том, что это проверяется в время компиляции , тогда как приведение проверяется в время выполнения .

Вы всегда хотите проверять время компиляции, если можете его получитьв противном случае вы рискуете скомпилировать, развернуть в производство, а затем взорваться во время выполнения в производстве.

1 голос
/ 17 июня 2011

Если можете, избегайте сотворения всех вместе:

private void myMethod(List<YourType> myLists) {

   for (YourType val : myLists) {
       val.getMyOtherMethod(); // for example
   }

}
0 голосов
/ 17 июня 2011

вы можете избежать приведения всех вместе с универсальными подстановочными знаками

private void myMethod(List<? extends YourInterface> myLists) {

   for (YourInterface val : myLists) {
       val.getMyOtherMethod(); // for example
   }

}

имеет преимущество в том, что доступны другие типы, которые реализуют с YourInterface этим методом

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...