Pregunta

Tenemos algunas pruebas unitarias que compilar y ejecutar bien en Eclipse 3.4, pero cuando tratamos de compilar usando javac, falla. He conseguido reducir el código a algo pequeño y autónomo, por lo que no tiene dependencias externas. El código en sí no tiene mucho sentido porque es todo fuera de contexto, pero eso no importa - sólo hay que averiguar por qué javac no le gusta esto:

public class Test {

    public void test() {
        matchOn(someMatcher().with(anotherMatcher()));
    }

    void matchOn(SubMatcher matcher) {}

    SubMatcher someMatcher() {
        return new SubMatcher();
    }

    Matcher anotherMatcher() {
        return null;
    }
}

interface Matcher <U, T> {}

class BaseMatcher implements Matcher {
    public BaseMatcher with(Matcher<?,?> matcher) {
        return this;
    }
}

class SubMatcher extends BaseMatcher {
    @Override
    public SubMatcher with(Matcher matcher) {
        return this;
    }
}

He tratado con JDK 1.5.0_10 y 1.6.0_13, con el mismo resultado:

Test.java:6: matchOn(test.SubMatcher) in test.Test cannot be applied to (test.BaseMatcher)
                matchOn(someMatcher().with(anotherMatcher()));
                ^
1 error

Creo que esto es perfectamente válido de Java. El método SubMatcher.with () devuelve un tipo más específico que BaseMatcher.with (), pero el compilador parece pensar que el tipo de retorno es BaseMatcher. Sin embargo, es posible que el compilador de Eclipse está permitiendo incorrectamente algo que no debería ser.

¿Alguna idea?

¿Fue útil?

Solución

en BaseMatcher es necesario especificar los parámetros de tipo:

public SubMatcher with(Matcher<?, ?> matcher) {

con el fin de permitir que javac para que coincida con su método de with

PS

mi humilde opinión es un error del compilador Eclipse

Otros consejos

Lo hice construir con éxito mediante la adición de <?,?> a Matcher en SubMatcher.with:

class SubMatcher extends BaseMatcher {
    @Override
    public SubMatcher with(Matcher<?,?> matcher) {
        return this;
    }
}

Sin esto, la firma del método es diferente de la base. Me pregunto si hay un error en la comprobación de @Override que no se da cuenta de esto.

Comprobar el cual JRE o JDK está compilando con tanto en Eclipse y terminal. Tal podría ser el tema de versión.

A mí me funciona:

$ java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-****-2009_07_23_10_21-b00)
OpenJDK 64-Bit Server VM (build 16.0-b06, mixed mode)
$ javac -XDrawDiagnostics Test.java 
$

Recuerdo vagamente un informe de error tal, pero no puedo darle un enlace a ella en este momento.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top