3

I am learning Java 8 . I am trying to create custom Predicate chaining method as below

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

    default Predicate<T> and(Predicate<T> other){
        return t -> this.test(t) && other.test(t);
    }
}

When i define my Predicate as above it works , but if i try to implement the same as below it gives me StackOverflow exception

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

    default Predicate<T> and(Predicate<T> other){
        //return t -> this.test(t) && other.test(t);
        return new Predicate<T>() {
            @Override
            public boolean test(T t) {
                return test(t) && other.test(t);
            }
        };
    }
}

Can you please explain me why it is giving me stackoverflow exception in Java 7 style whereas do not give any exception if i define it using lambda.

Ishant Gaurav
  • 1,183
  • 2
  • 13
  • 32
  • 2
    `this` in a lambda doesn't refer to the lambda. In an anonymous inner class, `this` refers to the instance of the inner class. – Peter Lawrey Sep 29 '18 at 06:28

1 Answers1

6

test(t) is a recursive call to itself, since the unqualified call is to the anonymous class.

So would this.test(t) be, since this refers to the anonymous class.

Change to Predicate.this.test(t)

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

    default Predicate<T> and(Predicate<T> other){
        //return t -> this.test(t) && other.test(t);
        return new Predicate<T>() {
            @Override
            public boolean test(T t) {
                return Predicate.this.test(t) && other.test(t);
            }
        };
    }
}

See answer to "Lambda this reference in java" for more detail.

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • As per your answer this should also not work default Predicate and(Predicate other){ return t -> this.test(t) && other.test(t); } . But this is working fine . How it is so ? – Ishant Gaurav Sep 29 '18 at 08:40
  • 1
    @IshantGaurav Because a lambda is not an anonymous class, and it is explained in the link I provided. – Andreas Sep 29 '18 at 17:21