zoukankan      html  css  js  c++  java
  • JAVA_闭包

    之前总结了下匿名内部类,想到了js的闭包,那么java有没有闭包相关的动作呢?
    回去翻了翻《JAVA编程思想》发现有闭包和回调的相关说明,但书中的说法不是很好理解,因为有些兴趣,仿照着书中代码做个例子看看。稍微研究下。代码如下:

    // 增加计数功能定义
    // 注意,接口只存在一个void increment(),所以所有实现它的对象中,
    // 只存在public的void increment,其他的成员都是private
    interface Incremental {
        void increment();
    }
    // 调用者:保存计数功能对象,并调用
    class Caller{
        private Incremental callbackReference;
        Caller(Incremental incrementable){callbackReference = incrementable;}
        void go(){callbackReference.increment();}
    }
    // 实现class1:简单的实现增加计数
    class Callee1 implements Incremental {
        private int num = 0;
        @Override
        public void increment() {
            System.out.println("Callee1:增加计数功能实现"+(++num));
        }
    }
    // 实现class2:在实现功能的同时实现回调
    class Callee2 extends Callback implements Incremental {
        private int num = 0;
        @Override
        public void increment(){
            System.out.println("Callee2:增加计数功能实现"+(++num));
            super.increment();
        }
        // 闭包,内部类Closure调用了外部变量num
        private class Closure implements Incremental {
            @Override
            public void increment() {
                System.out.println("Callee2-Closure:增加计数功能实现"+(++num));
                Callee2.super.increment();
            }
        }
        public Incremental getCallbackReference(){
            return  new Closure();
        }
    }
    // 回调用类
    class Callback {
        public void increment(){System.out.println("回调内容执行...");}
        static void fun(Callback myIncrement){myIncrement.increment();}
    }
    
    public class test_closure {
        // 执行部分
        public static void main(String[] arge){
            // 简单的实现,使用调用者调用
            Caller caller1 = new Caller(new Callee1());
            caller1.go();
            caller1.go();
            // 结果:
            // Callee1:增加计数功能实现1
            // Callee1:增加计数功能实现2
    
            // 追加回调方法的实现
            // 回调对象执行实现对象
            Callee2 callee2 = new Callee2();
            Callback.fun(callee2);
            // 结果:
            // Callee2:增加计数功能实现1
            // 回调内容执行...
    
            // 使用调用者调用
            Caller caller2 = new Caller(callee2.getCallbackReference());
            caller2.go();
            caller2.go();
            // 结果:
            // Callee2-Closure:增加计数功能实现2
            // 回调内容执行...
            // Callee2-Closure:增加计数功能实现3
            // 回调内容执行...
        }
    }
    

    以上是经过理解并追加注释的结果,书上的代码例子,不敲下来实在太难理解了……
    注意是Callee1只是对比用,没回调和闭包,Callee2中存在内部类,内部类调用了Callee2的私有变量num——闭包;Callee2的getCallbackReference方法返回内部类,而内部类中,实现了接口的同时,调用了回调类的内容——回调。
    ……说实话,不知道是思维方式还是理解能力的问题,觉得这个例子实在很麻烦。还是自己弄个例子吧。


    闭包

    那么,首先是闭包。说道闭包,还是js比较多,那么,这里随便写个例子。

    function Incrementable(){
      var num = 0;
      return function(){  // 这里,类似java直接返回内部类
        num = num+1;
    	console.log(num)
      }
    }
    var Callee = Incrementable();
    Callee();
    Callee();
    console.log(num);
    
    // 执行结果:
    1
    2
    Uncaught ReferenceError: i is not defined
    

    这个例子其实和之前java的闭包例子是一样,同样是自增的实现,内部变量num在Incrementable之外无法访问,但是Incrementable内的function内部可以访问。
    将以上的例子转成java的话是这样的:

    // 自增长接口和实现类
    interface Incrementable{
        void increment();
    }
    class Callee {
        private int num = 0;
        public Incrementable getIncrementable(){
            return new Incrementable(){
                @Override
                public void increment() {
                    System.out.println("Callee:增加计数功能实现"+(++num));
                }
            };
        }
    }
    public class test_closure2 {
        // 执行部分
        public static void main(String[] arge){
            Callee callee = new Callee();
            callee.getIncrementable().increment();
            callee.getIncrementable().increment();
            callee.getIncrementable().increment();
            // 结果:
            // Callee:增加计数功能实现1
            // Callee:增加计数功能实现2
            // Callee:增加计数功能实现3
        }
    }
    

    可以看到,java类似js一样的,对内部的num变量实现了改变。一般工作中可能不这么写,但是翻翻源码,如此定义的方式还是很多的。原因在于这是一种不改变原本结构进行更新的方法,也可以根据结构的变化,切换功能,需要注意。

  • 相关阅读:
    馒头国家标准公布:应是圆形或椭圆形(图)
    完全用C#写的SharpOS 0.0.1版发布
    c#操作c/c++的Dll文件
    研究发现GSM信号影响睡眠
    解决QQ与360的终极解决方案
    分享一个参数检查的类
    问题是问题,可是出路呢?
    读《码斗士修炼之路》有感
    我看博客园之争论
    关于ORM的一点思考
  • 原文地址:https://www.cnblogs.com/changfanchangle/p/8865938.html
Copyright © 2011-2022 走看看