鍍金池/ 問答/Java  Python  網(wǎng)絡(luò)安全/ java8 Predicate接口中的negate()默認(rèn)方法用java7如何實(shí)

java8 Predicate接口中的negate()默認(rèn)方法用java7如何實(shí)現(xiàn)?

negate()源碼為:

default Predicate<T> negate() {

    return (t) -> !test(t);

}

我理解的可以轉(zhuǎn)換為:

default Predicate<T> negate() {

    return new Predicate<T>() {

        public boolean test(T t) {

            !test(t);

        }

    };

}

但是這樣轉(zhuǎn)化的話test()就成了死循環(huán)了啊,是我理解的不對嗎?正確的轉(zhuǎn)換是什么,請大家多多指教

回答
編輯回答
若相惜

首先給出我認(rèn)為的正確寫法吧(我copy了Predicat類,然后改名為PredicateExt進(jìn)行重寫)

default PredicateExt<T> negate() {
        PredicateExt<T> predicate = this;
        PredicateExt<T> otherPredicate = new PredicateExt<T>() {
            @Override
            public boolean test(T t) {
                return !predicate.test(t);
            }
        };
        return otherPredicate;
    }

再來看看Java8中Predicate.negate到底表達(dá)的是什么意思

  1. Predicate肯定是一個(gè)類,(t) -> !test(t)這種lamdba語法也只是表示Predicate的一個(gè)對象而已
  2. default方法就是代表了Predicate對象的某個(gè)實(shí)例方法

因此結(jié)合以上兩點(diǎn),可以直接看出Predicate.negate代表Predicate的某個(gè)對象A執(zhí)行時(shí),根據(jù)A的執(zhí)行結(jié)果再次創(chuàng)建了一個(gè)新Predicate的對象B
所以,要換種方式來表示Predicate.negate方法,肯定也要體現(xiàn)出A,B兩個(gè)新舊對象,并且該方法的執(zhí)行結(jié)果是根據(jù)A的執(zhí)行結(jié)果體現(xiàn)出來的

再來說說題主為什么會(huì)死循環(huán),雖然題主已經(jīng)明顯new了一個(gè)Predicate對象,這里體現(xiàn)了A,B兩個(gè)新舊對象,但是后面的執(zhí)行結(jié)果并沒有體現(xiàn)出是根據(jù)A的執(zhí)行結(jié)果來產(chǎn)生B的
主要在于里面的在重寫B(tài)的test方法時(shí),是再調(diào)用test方法的,只是前面加了一個(gè)!,所以顯然這里調(diào)用的是B的Predicatetest方法,當(dāng)然就是循環(huán)調(diào)用了,可別指望它能調(diào)用A的Predicate方法,因?yàn)槟阏谥貙戇@個(gè)新Predicate的方法,這里的this指針,肯定是指向B的

鑒于此,既然在B里面重寫方法時(shí)this指針是指向B的,那就在外面顯示的把A的對象指示出來,然后再B中重寫時(shí),顯示用的A的方法進(jìn)行執(zhí)行,這樣就可以了,所以才有上面的寫法

從運(yùn)行的debug來看,以前的方式和現(xiàn)在重寫的方式,在新的B對象中,都包含了以前的舊對象A的,所以是可行的

clipboard.png

2017年6月26日 23:17