Sto facendo qualcosa di sbagliato di Java 8 non riesce a fare inferenza di tipo per varargs?

voti
-1

So che ci sono alcune domande relative tipo inferenza già ma sembra che ho trovato qualcosa di nuovo.

Così ho un semplice sistema di diverse azioni che voglio correre e costruttori per loro:

Pacchetto foo.bar.buzz.fail.actionscontiene:

Un'interfaccia:

package foo.bar.buzz.fail.actions;

public interface Action {
    void perform();
}

Un'azione astratta che non implementa l'interfaccia ed è il pacchetto-privato :

package foo.bar.buzz.fail.actions;

class AbstractAction {
    private final int foo;

    AbstractAction(int foo) {
        this.foo = foo;
    }

    int getFoo() {
        return foo;
    }
}

E poi ho le azioni di coppia,

Azione Foo:

package foo.bar.buzz.fail.actions;

public class FooAction extends AbstractAction implements Action {
    public FooAction(int foo) {
        super(foo);
    }

    @Override
    public void perform() {
        System.out.println(Hello from foo!);
    }
}

E l'azione Bar:

package foo.bar.buzz.fail.actions;

public class BarAction extends AbstractAction implements Action {
    private final int bar;

    public BarAction(int foo, int bar) {
        super(foo);
        this.bar = bar;
    }

    @Override
    public void perform() {
        System.out.println(Hello, from bar with: foo= + getFoo() + , and bar= + bar);
    }
}

E nel pacchetto foo.bar.buzz.failHo una serie di costruttori di tali azioni. Un costruttore e di coppia costruttori generici, che sono specifici per l'azione:

package foo.bar.buzz.fail;

import foo.bar.buzz.fail.actions.Action;
import foo.bar.buzz.fail.actions.BarAction;
import foo.bar.buzz.fail.actions.FooAction;

public class Actions {

    public static FooActionBuilder newFooAction() {
        return new FooActionBuilder();
    }

    public static BarActionBuilder newBarAction() {
        return new BarActionBuilder();
    }

    public static class FooActionBuilder extends AbstractActionBuilder<FooActionBuilder, FooAction> {
        @Override
        public FooAction build() {
            return new FooAction(foo);
        }
    }

    public static class BarActionBuilder extends AbstractActionBuilder<BarActionBuilder, BarAction> {
        private int bar;

        @Override
        public BarAction build() {
            return new BarAction(foo, bar);
        }

        public BarActionBuilder withBar(int bar) {
            this.bar = bar;
            return this;
        }
    }

    public static abstract class AbstractActionBuilder<T extends AbstractActionBuilder, R extends Action> {
        protected int foo;

        public T withFoo(int foo) {
            this.foo = foo;
            return (T) this;
        }

        public abstract R build();
    }
}

E poi sto cercando di mappa piatta serie di azioni per un numero di semi nello stesso foo.bar.buzz.failpackage:

package foo.bar.buzz.fail;

import foo.bar.buzz.fail.actions.Action;
import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Stream;

import static foo.bar.buzz.fail.Actions.newBarAction;
import static foo.bar.buzz.fail.Actions.newFooAction;
import static java.util.stream.Collectors.toList;

public class App {

    public static Integer[] seeds = {
            1, 2, 3
    };

    public static void main(String[] args) throws Exception {
        Collection<Action> actions = Arrays.stream(seeds)
                .flatMap((foo) -> Stream.of(
                        newFooAction()
                                .withFoo(foo)
                                .build(),
                        newBarAction()
                                .withFoo(foo)
                                .withBar(getBar(foo))
                                .build()))
                .collect(toList());

        for(Action action: actions) {
            action.perform();
        }
    }

    private static int getBar(int foo) {
        return foo * foo;
    }
}

Il mio problema è l'essere che non riesce a compilare con messaggio di errore:

Errore: (18, 25) Java: tipi incompatibili: tipo di elemento varargs formale foo.bar.buzz.fail.actions.AbstractAction & foo.bar.buzz.fail.actions.Action non è accessibile dalla classe foo.bar.buzz.fail .app

Così sembra che le cose compilatore che sto passando AbstractActionclassi per varargs metodi quando dovrebbe pensare Action. Mi viene pazzo qui o fa apparire come un bug del compilatore?

Note :

  • Se almeno un elemento di varargs è un Actionesplicito allora funziona (I può lanciare uno dei parametri o semplicemente utilizzare un'istanza anonima della Actioninterfaccia).

  • Se tiro la chiamata varargs di carta piatta allora funziona.

  • Ovviamente, se faccio AbstractActionpubblica che funziona.

  • Se cambio i costruttori di ritornare Actional posto di tipi bambini allora funziona.

  • Non ho provato su Java 9 e io non voglio davvero - ho scelto come target Java 8 comunque.

il layout della confezione / classi è la seguente:

foo.bar.buzz.fail ->
    Actions.java
    App.java

foo.bar.buzz.fail.actions ->
    Action.java
    AbstractAction.java
    BarAction.java
    FooAction.java
È pubblicato 08/02/2018 alle 03:44
fonte dall'utente
In altre lingue...                            


1 risposte

voti
0

Utilizzare un parametro di tipo esplicito:

.flatMap((foo) -> Stream.<Action> of(

Il fatto che non funziona al di fuori della lambda sembra essere un errore in Eclipse, dal momento che javac rifiuta ancora. Ho presentato questo come Eclipse Bug 530.915 , che ha più dettagli.

Risposto il 08/02/2018 a 20:44
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more