21

I did this:

public class LambdaConflict
{
    public static void main(String args[]){
        //*
        System.out.println(LambdaConflict.get(
            (str) -> "Hello World!! By ME?"
        ));
        /*/
        System.out.println(LambdaConflict.get(new Intf<String> (){
            @Override public String get1(String str){
                return "Hello World!! By get1 " + str;
            }
        }));
        /*****/
    }

    public static String get(Intf<String> i, boolean b){
        return i.get1("from 1");
    }
}

interface Intf<T>
{
    public T get1(T arg1);

    public T get2(T arg1);
}

and get this exception:

incompatible types: Intf is not a functional interface multiple non-overriding abstract methods found in interface Intf Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output 1 error

Is there any condition that I can't use lambda to replace anonymous class?

nawfal
  • 70,104
  • 56
  • 326
  • 368
Valen
  • 1,693
  • 1
  • 20
  • 17

4 Answers4

29

No. There is no way to "overcome" this. A functional interface must have only one abstract method. Your interface has two:

interface Intf<T> {
    public T get1(T arg1);
    public T get2(T arg1);
}

Note: You don't need to annotate your interface as mentioned in comments. But you can use the @FunctionalInterface annotation to get compile time errors if your interface is not a valid functional interface. So it brings you a little bit more security in your code.

For more see e.g. http://java.dzone.com/articles/introduction-functional-1

Ragunath Jawahar
  • 19,513
  • 22
  • 110
  • 155
Thomas Uhrig
  • 30,811
  • 12
  • 60
  • 80
  • 1
    Thanks for the tip about `@FunctionalInterface`! I forget it has special properties. Also, I found upgrading to the very latest JDK8 patch from Oracle also helps to improve error messages. Older versions of JDK8 may sometimes allow code above to compile, but fail with an `java.lang.AbstractMethodError` at run-time. Newer versions will reject at compile-time. – kevinarpe Mar 29 '16 at 06:36
8

Just for reference and to enrich the answers already given:

As per JSR-335: Lambda Expressions for the Java Programming Language, in section Lambda Specification, Part A: Functional Interfaces it says:

A functional interface is an interface that has just one abstract method (aside from the methods of Object), and thus represents a single function contract. (In some cases, this "single" method may take the form of multiple abstract methods with override-equivalent signatures inherited from superinterfaces; in this case, the inherited methods logically represent a single method.)

So, what you need is to either provide a default implementation for one of your methods or put one of your methods in a different interface.

Edwin Dalorzo
  • 76,803
  • 25
  • 144
  • 205
3

Think about it:

  • How should the compiler know if you want to override get1 or get2?

  • If you only override get1, what will be get2's implementation? Even the code you commented out won't work because you don't implement get2...

There are reasons for this limitation...

Idan Arye
  • 12,402
  • 5
  • 49
  • 68
1

As stated by @Thomas-Uhrig, Functional Interfaces can only have one method.

A way to fix this, primarily because you never use public T get2(T arg1);, is to change the Intf<T> interface to:

@FunctionalInterface
interface Intf<T>
{
    public T get1(T arg1);
}
DirkyJerky
  • 1,130
  • 5
  • 10