Hä? Lambda-Ausdruck geht, Methoden-Referenz nicht

LimDul

Top Contributor
Folgende Konstruktor-Signatur

Java:
public KlasseX(Supplier<KlasseY> klasseYSupplier, Consumer<KlasseY> klasseYConsumer);

Weiterhin gibt es eine KlasseZ mit:
Java:
public class KlasseZ() {
public KlasseY getY();
public void setY(KlasseY y);
Klassische Getter und Setter

Gegeben ist sinnbildlich folgender Code:
Java:
List<? extends KlasseZ> liste = ermittleListe();
// Variante A
liste.stream().map(z->new KlasseX(z::getY, z::setY))....
// Variante B
liste.stream().map(z->new KlasseX(()->z.getY(), y->z.setY(y)))....
Variante A kompiliert in Eclipse, aber nicht im Maven-Build
Variante B kompiliert in Eclipse, und im Maven-Build

Hääh?
 
Zuletzt bearbeitet:
Ergänzt, ich hab den Code gerade hier im Forum geschrieben - die Klammerzahlen stimmen schon im echten 🙂 (Ansonsten würde Eclipse ja auch Fehler werfen).

Der Compile Error ist auch
incompatible types: invalid method reference
getY() in KlasseZ is defined in an inaccessible class or interface
KlasseZ liegt übrigens im gleichen Projekt wie der Code ....
 
Welche Fehlermeldung bekommst du denn von Eclipse und/oder dem JDK/javac Compiler und wie sieht der tatsächlich von dir verwendete Code aus?
Ersteinmal, lass uns das Ganze mal in eine MCVE Form bringen, die keine Schreibfehler enthält und den tatsächlichen verwendeten Code nachstellt:
Java:
import java.util.*;
import java.util.function.*;
public class KlasseX {
  static class KlasseY {}
  static class KlasseZ {
    KlasseY getY() {
      return null;
    }
    void setY(KlasseY y) {}
  }
  public KlasseX(Supplier<KlasseY> klasseYSupplier, Consumer<KlasseY> klasseYConsumer) {}
  public static void main(String[] args) {
    List<? extends KlasseZ> liste = new ArrayList<>();
    // Variante A
    liste.stream().map(z -> new KlasseX(z::getY, z::setY));
    // Variante B
    liste.stream().map(z -> new KlasseX(() -> z.getY(), y -> z.setY(y)));
  }
}
Das kompiliert in Eclipse (Compiler Compliance Level = Java 11) und auch mit javac (unter Maven) mit JDK 16 EA und source/target/release = Java 11.
 
Ich muss das mal versuchen zu bereinigen und in ein minimales Beispiel zu bringen. Wir sind hier noch auf java 8 unterwegs. Ich war nicht der einzige der das Problem hatte, Kollegen in einem anderen Projekt an analoger Stelle auch. Ich hatte die Hoffnung das jemand da eine Java Spec aus dem Hut zieht.
 
Ok, minimales Beispiel:

Logikklasse (Wo der nicht kompilierende Code liegt)
Java:
package de.javaforum.test;

import java.util.Collections;
import java.util.List;

public class LogikKlasse {

    public static void main(String[] args) {

        List<? extends BeanKlasse> list = Collections.emptyList();

        list.stream().map(b -> new WrapperKlasse(b::getValueKlasse, b::setValueKlasse));
    }

}

BeanKlasse (nur getter & setter)
Java:
package de.javaforum.test;

public class BeanKlasse {

    private ValueKlasse valueKlasse;

    public ValueKlasse getValueKlasse() {
        return valueKlasse;
    }

    public void setValueKlasse(ValueKlasse valueKlasse) {
        this.valueKlasse = valueKlasse;
    }

}

ValueKlasse (Ohne Inhalt)
Java:
package de.javaforum.test;

public class ValueKlasse {

}

WrapperKlasse (die den Consumer/Supplier bekommt)
Java:
package de.javaforum.test;

import java.util.function.Consumer;
import java.util.function.Supplier;

public class WrapperKlasse {

    private Supplier<ValueKlasse> supplier;
    private Consumer<ValueKlasse> consumer;

    public WrapperKlasse(Supplier<ValueKlasse> supplier, Consumer<ValueKlasse> consumer) {
        this.supplier = supplier;
        this.consumer = consumer;
    }

}

Eclipse:
- Kompiliert
- Lässt sich ausführen

Maven:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project redacted: Compilation failure
[ERROR] /C:/Development/redacted/src/main/java/de/javaforum/test/LogikKlasse.java:[18,50] incompatible types: invalid method reference
[ERROR] getValueKlasse() in de.javaforum.test.BeanKlasse is defined in an inaccessible class or interface

Eclipse-Compliance Level: Java 1.8
Maven:
Code:
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
 
Mache ich das ? extends bei der Liste weg, kompiliert es auch in Maven. Warum? Mir sind die Probleme mit solchen Listen bzw generell dem ? extends durchaus bewusst, aber an der Stelle verstehe ich nicht warum es in Maven nicht klappt - jedes Objekt der Liste hat die Methode getY bzw. setY

Nachtrag:
Versionen
Maven: 3.3.9 und 3.5.4
Eclipse: 2019-06
JDK: openjdk version "1.8.0_212-3-redhat"
 

Zurück
Oben