Groovy компилятор вызывает неправильный перегруженный Java-метод - PullRequest
0 голосов
/ 21 марта 2012

Я выполнил поиск в StackOverflow, прежде чем опубликовать этот вопрос, но не смог найти правильный ответ.Извините, если это репост.Моя проблема заключается в следующем:

У меня есть метод, который перегружен в моем классе Java:

class ABC{

    public boolean doSomething(String path, ArrayList<SomeObject> objList){
        // calling the method below in a loop
    }

    public boolean doSomething(String path, SomeObject obj){
       // Some code here
    }
}

Я вызываю вышеуказанный класс из моего Groovy кода, как это:

void performDoSomething(ABC abc, String path, String[] strList){
    def list = []
    for (str in strList) {
        SomeObject sObj = new SomeObject(str)    // EDIT: sorry I missed this line before
        list.add(sObj)
    }
    if (abc) abc.doSomething(path, list)
}

Проблема в том, что Groovy-компилятор вызывает метод abc.doSomething (String str, SomeObject obj) вместо метода abc.doSomething (String str, ArrayList objList).

Я использую Eclipse IDE с плагином Grails (STS), и это часть более крупного проекта Grails (у нашей компании много унаследованного кода в Java).

Любые идеи о том, какчтобы это исправить?
Спасибо за потраченное время!

РЕДАКТИРОВАТЬ: Я тоже пробовал abc.doSomething (путь, список как ArrayList), но я получаю тот же результат ..

Ответы [ 3 ]

2 голосов
/ 21 марта 2012

Можете ли вы воспроизвести это на простом примере, используя упомянутые вами классы? Я пытался, но получил ожидаемое поведение.

SomeObject.java:

public class SomeObject {
    public String what;
    public SomeObject(String what) {
        this.what = what;
    }
}

ABC.java:

import java.util.List;

public class ABC {
    public void doSomething(String path, List<SomeObject> objects) {
        System.out.println("Doing something with many objects");
        for (SomeObject obj : objects) {
            doSomething(path, obj);
        }
    }

    public void doSomething(String path, SomeObject obj) {
        System.out.println("Doing something with: " + obj.what);
    }
}

test.groovy:

void performDoSomething(ABC abc, String path, String[] strList){
    def list = []
    for (str in strList) {
        SomeObject sObj = new SomeObject(str)    // EDIT: sorry I missed this line before
        list.add(sObj)
    }
    if (abc) abc.doSomething(path, list)
}

performDoSomething(new ABC(), 'some path', ['hello', 'world'] as String[])

Я запускаю это (в том же каталоге, что и файлы):

javac *.java
groovy test.groovy

И вывод, который я получаю:

Doing something with many objects
Doing something with: hello
Doing something with: world

Это означает, что Groovy вызывает правильный перегруженный метод, doSomething(String, List<SomeObject>). Это то, что ожидается, поскольку Groovy использует информацию о типе среды выполнения для методов, чтобы решить, какую перегруженную версию вызывать (пример этого можно найти здесь ). Я бы не рекомендовал изменить сигнатуру doSomthing , как предложено , так как это излишне загрязнит интерфейс класса; проблема, вероятно, где-то еще.

1 голос
/ 21 марта 2012

Хорошо, я понял ответ.Это проблема IDE затмения, мне пришлось запустить команду "grails clean", и проект был перестроен.Теперь Groovy код вызывает правильный метод Java.

1 голос
/ 21 марта 2012

Самый простой ответ - убедиться, что ваша перегрузка вовсе не двусмысленна.

Сделайте, чтобы у двух вызовов были совершенно разные API, и посмотрите, исчезнет ли проблема или новые сообщения об ошибках укажут на причудливую проблему.

public class ABC {
  public boolean doSomething(String path, int ignored, ArrayList<Object> objList){
    // calling the method below in a loop
  }

  public boolean doSomething(String path, Object obj){
   // Some code here
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...