从作为参数传递的lambda访问匿名类的其他方法

时间:2017-12-08 18:37:59

标签: java lambda java-8

让我们说我有一个方法可以创建一个匿名对象并将其存储在某个地方。这个匿名对象在其方法中调用lambdas,它们已作为参数传递。

public class myCallBackManager {

    private List<MyCallBack<?>> callBackList = new LinkedList<MyCallBack<?>>();

    public <T> void addCallBack(Consumer<MyCallBack<T> onCall, Runnable something){
        callBackList.add(new MyCallback<T>() {
            @Override
            protected void call(MyCallback<T> callback) {
                onCall.accept(callback);
            }
            @Override
            protected void doSomething() {
                something.run());
            }
        }
    }

    public void runAll() {
        for (MyCallback<?> myCallback : callBackList) {
            myCallback.call();
        }
    }
}

这会在内部存储这些对象,并要求它们稍后再执行。

但是,我想补充一点:

public static void main(String[] args) {

    Runnable someRunnable = () -> System.out.println("Doing something");

    MyCallBackManager myCallBackManager = new MyCallbackManager();
    myCallBackManager.<SomeObject> addCallback(
            (callback) -> {
                doSomething(); // WON'T WORK
                System.out.println(callback.toString());
            },
            someRunnable
    };

    myCallBackManager.runAll();

}

这里,我试图从onCall lambda调用doSomething(),因为它是在调用匿名函数的call()时运行的。问题是,我没有处理仍然不存在的对象,这会发生,所以很明显它无法调用它的方法。有没有办法从lambda调用doSomething()?

在这种特殊情况下有一些解决方法,例如调用someRunnable.run()而不是尝试访问doSomething()方法,但我特别要求一种方法来调用该方法。

1 个答案:

答案 0 :(得分:0)

这是一个解决方案。你真的想做什么?

import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;

public class Test {

    public static class MyCallback<T> {

        public void call() {
            System.out.println("Test.MyCallback.call()");           
        }

        protected void call(MyCallback<?> callback) {
            System.out.println("Test.MyCallback.call(MyCallback<?>)");          
        }

        protected void doSomething() {
            System.out.println("Test.MyCallback.doSomething()");            
        }

    }

    static public class CallBackManager {

        private List<MyCallback<?>> callBackList = new LinkedList<>();

        public void addCallBack(Consumer<MyCallback<?>> onCall, Runnable something){
            callBackList.add(new MyCallback<Object>() {
                @Override
                protected void call(MyCallback callback) {
                    onCall.accept(callback);
                }
                @Override
                protected void doSomething() {
                    something.run();
                }
            }
                    );
        }

        public void runAll() {
            for (MyCallback<?> myCallback : callBackList) {
                myCallback.call();
            }
        }
    }

    public static void main(String[] args) {

        Runnable someRunnable = () -> System.out.println("Doing something");

        CallBackManager myCallBackManager = new CallBackManager();
        myCallBackManager.addCallBack(
                (MyCallback<?> callback) -> {
                    callback.doSomething(); // WON'T WORK
                    System.out.println(callback.toString());
                },
                someRunnable
                );

        myCallBackManager.runAll();

    }

}

你永远不会在Test.CallBackManager.addCallBack(Consumer&gt;,Runnable)中使用onCall,也许这也是问题所在。

或者你正在尝试这个:

import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;

public class Test {

    public static class MyCallback<T> {

        public void call() {
            System.out.println("Test.MyCallback.call()");           
        }

        protected void call(MyCallback<?> callback) {
            System.out.println("Test.MyCallback.call(MyCallback<?>)");          
        }

        protected void doSomething() {
            System.out.println("Test.MyCallback.doSomething()");            
        }

        @Override
        public String toString() {
            System.out.println("Test.MyCallback.toString()");           
            return "[CLASS Test.MyCallback<T>]";
        }

    }

    static public class CallBackManager {

        private List<MyCallback<?>> callBackList = new LinkedList<>();

        public void addCallBack(Consumer<MyCallback<?>> onCall, Runnable something){
            callBackList.add(new MyCallback<Object>() {
                @Override
                protected void call(MyCallback callback) {
                    onCall.accept(callback);
                }
                @Override
                protected void doSomething() {
                    something.run();
                }
            }
                    );
        }

        public void runAll() {
            for (MyCallback<?> myCallback : callBackList) {
                myCallback.call();
                myCallback.call(myCallback);//OR THIS?
            }
        }
    }

    public static void main(String[] args) {

        Runnable someRunnable = () -> System.out.println("Doing something");

        CallBackManager myCallBackManager = new CallBackManager();
        myCallBackManager.addCallBack(
                (MyCallback<?> callback) -> {
                    callback.doSomething(); // WON'T WORK
                    System.out.println(callback.toString());
                },
                someRunnable
                );

        myCallBackManager.runAll();

    }

}