0

just trying out things in java, found following issue.

DefaultAndStaticMethodMain.java:8: error: not a statement
        implementation1::sendNotification;
        ^
1 error

Following is my code.

ParentInterface:

public interface ParentInterface {
    default void callForCompletion() {
        System.out.println("<<<< Notification sending completed. >>>>");
    }
}

Child interface:

public interface ChildInterface extends ParentInterface {
    public abstract void sendNotification();

    static String printNotificationSentMessage() {
        return "Notification is sent successfully.";
    }
}

Implementation 1:

public class Implementation1 implements ChildInterface {
    @Override
    public void sendNotification() {

        System.out.println("Implementation --- 1");
        System.out.println("Sending notification via email >>>");
    }
}

Implementation 2:

public class Implementation2 implements ChildInterface {
    @Override
    public void sendNotification() {
        System.out.println("Implementation ---- 2.");
        System.out.println("Sending notification via SMS >>>");
    }
}

Main method:

public class DefaultAndStaticMethodMain {
    public static void main(String[] args) {
        Implementation1 implementation1 = new Implementation1();
        implementation1::sendNotification; // Compilation error as shown above.

        Implementation2 implementation2 = new Implementation2();
        implementation2.sendNotification();

        // Following works fine.
//        Arrays.asList(implementation1, implementation2).stream().forEach(SomeInterfaceToBeRenamed::sendNotification);
    }
}

I am not sure what am I doing wrong, I have JDK 13 installed in local machine and working with IntelliJ 2019.3 with JDK 11. I checked that IntelliJ supports JDK 13

Thanks.

Update By mistake I left a semi-colon over there, removed it, please check again.

Bilbo Baggins
  • 2,899
  • 10
  • 52
  • 77
  • 2
    That's not valid Java, even without the errant `;`. What are you actually trying to do? – Slaw Feb 22 '20 at 12:34
  • 2
    What do you intend to happen from just writing a method reference by itself? If you write just `1 + 1;` you also get an error, because it's not a statement and has no effect. The error message tells you this exactly: **error: not a statement**. – kaya3 Feb 22 '20 at 12:34
  • may be odd number of > or < generates this issue. – maniaq Feb 22 '20 at 12:40
  • "Double colon operator"? there is no such operator in java, it is a [3.11. Separators](https://docs.oracle.com/javase/specs/jls/se13/html/jls-3.html#jls-3.11)- given statement is not valid (like just having a variable alone), could be something *strange* like `((Runnable) implementation1::sendNotification).run()`, but why not just call the method? – user85421 Feb 22 '20 at 12:46
  • or it could be assigned to a variable/field: `Runnable r = implementation1::sendNotification;` and executed later on `r.run();` or passed as argument to another method to be executed there – user85421 Feb 22 '20 at 12:59

2 Answers2

5

What do you intend for the implementation1::sendNotification; line to do? Judging by the implementation2.sendNotification(); line below it looks like you're trying to call sendNotification on implementation1, which is written like this:

implementation1.sendNotification();

The :: notation is a method reference, and (as the error message says) it an identifier, not a statement, and thus can't be a line on its own. Similarly you couldn't write implementation1; (a variable) or ChildInterface; (a class identifier) as a statement.

The .forEach(SomeInterfaceToBeRenamed::sendNotification); line compiles because you are passing the method reference to forEach(), and it in turn invokes each sendNotification() method.

dimo414
  • 47,227
  • 18
  • 148
  • 244
5

A method reference is not the same as a method call. Those are two distinct things.

  • A method call is a standalone expression, or, more precisely, an expression statement. That means that in your case implementation2.sendNotification() works, as you would expect.

  • A method reference, however,

    is used to refer to the invocation of a method without actually performing the invocation

    and is not a standalone expression. It can only be used where a lambda expression can also be used. A method reference as a standalone expression does not compile, just like an arithmetic expression without assignment (e.g. 3 + 17;). This is enforced by the Java Language Specification, § 14.8 and § 15.13.


More to read:

MC Emperor
  • 22,334
  • 15
  • 80
  • 130