精华内容
下载资源
问答
  • Java闭包之我见

    千次阅读 2012-03-07 11:02:14
    最近大家一直在讨论Java7及以后的Java8的应该加入哪些新特性,让Java看出来更“炫”,更...首先,我不明白为什么非要让Java这种几乎纯粹的面向对象的结构化设计语言里面加入闭包这种更适合函数式编程的特性,我并没有看

    最近大家一直在讨论Java7及以后的Java8的应该加入哪些新特性,让Java看出来更“炫”,更“瘦”,更“优雅”,其中呼声最高的就是闭包了,表达一下自己对这些特性的看法,仅个人观点,言语用词“过激”的地方完全是想更直观的表达观点,没有任何诋毁的意思,希望能和大家多多交流。

    首先,我不明白为什么非要让Java这种几乎纯粹的面向对象的结构化设计语言里面加入闭包这种更适合函数式编程的特性,我并没有看到有什么是闭包可以做到而Java现在做不到的,或者说是无法实现的且必须要这么做的,而且闭包的代码给人的感觉太随意,对于对象,结构明确的Java来说,突然冒出这么“一坨”代码,确实让人不爽,对于那些对编程风格要求严格或者完美的格式控来说,实在无法接受。现在有不少动态语言同时支持对象与函数式的编程,比如Scala,是很强大,但还是那句话,实在是没有看到必要性。

    其次,关于Lamda表达式,呼声也很高,Java本身不支持,但一些框架已经支持,比如Struts2,不知道用过Struts2的人有多少人在用这个表达式,个人感觉,应该不多,在一些语言之中,比如C#,用的会多一些,很多时间确实可以让代码很简洁,很方便,但如果通篇全是这东西,就有点太过了吧,又不得于代码的阅读,跟踪起来还不方便,依然是没有看到它的必要性。

    凡事没有绝对,以上这两个特性是C#里面的,确实有可取的地方,但实在不认为Java有什么理由非得加入这两个特性,不加入就过时了,完全落伍了,或者“XXXXJava已死了”,相反,个人感觉反而会让Java变的有点别扭,道家讲究“为腹不为目”,我觉得Java真的没有必要在什么所谓的特性上追求时尚,非得是别的语言有的我Java也有,才能算是进步。

    大家一直认为Java臃肿,应该瘦身,但首先臃肿不臃肿不是通过代码量来衡量的,臃肿更多是源于项目本身的设计存在问题,Java真的很冤枉,就像很多人说Android不如iOS流畅是因为Java性能不行,更有”专家“解释说是Java的GC不定时在垃圾回收,所以卡,卡的时候就是GC回收呢.....相信清楚的人都知道是Android本身的线程管理问题,就不要拿Java挡枪了,就算Java本身臃肿,刚问世的时候也是魔鬼身材,只是随着应用的广泛与需求,一点点的成长到现在,我想说的是不要被某个或者某些新生代的语言所谓的简洁与快捷所左右,等发展到Java这种程度,也许还不如Java也说不定,谁家孩子也不是一生出来就200斤,语言也需要时间的考验。

    很多特性大家认为可以让编程简单,确实,我以前用C编程的时候,觉得确实很多地方应该简洁点,太麻烦了,用Java编程,感觉非常痛快,几乎C时期的烦恼都没有了,用C#编程的时候,感觉更痛快,但是却没有那种非得这么痛快的感觉,觉得还是Java在这个度上做的更好一些。毕竟编程是件不简单的事,再简单也不简单,我想没有任何一个程序员希望编程成为一种傻瓜式的事情,谁都能做,这里引用郭老师一句名言“嫌我的相声不规矩,想要规矩?看升旗去呀“,差不多得了,多简单算简单呀?我想最简单的莫过于看别人编程了;最痛快的莫过于看别人编程,他还解决不了问题;呵呵,当然这是玩笑。

    还是那句话,个人认为Java真没有必要追求所谓的时尚,每次的更新虚拟机性能上的提高才是关键,必要的确实好的特性应该加入,非必要的,理解这种思路,用Java本身这种结构化的设计来实现,也挺好,不过倒确实希望Java可以加入像Objective-C里面的@property这样的特性,毕竟我想现在大家的代码里面,set/get确实有点多。

    个人愚见而已!

    展开全文
  • 写了一个测试java闭包的实例,在事件监听中用得比较多的设计模式!定义一个接口,通过接口来传递方法体/*** @author yaohw**/public interface Action{public void excute(Object arg);}消息接收类/*** @author ...

    写了一个测试java闭包的实例,在事件监听中用得比较多的设计模式!

    定义一个接口,通过接口来传递方法体

    /**

    * @author yaohw

    *

    */

    public interface Action{

    public void excute(Object arg);

    }

    消息接收类

    /**

    * @author yaohw

    *

    */

    public class To{

    private int j = 0;

    /* (non-Javadoc)

    * @see Action#excute(int)

    */

    public void update(Object i) {

    j = (Integer) i;

    System.out.println(j);

    }

    }消息发出者

    public class From{

    private int i = 12112;

    public void doWork(final Action action){

    //do sth

    action.excute(i);

    }

    }测试主方法

    public static void main(String[] args) {

    final To to = new To();

    From from = new From();

    from.doWork(new Action() {

    @Override

    public void excute(Object arg) {

    System.out.println("传方法");

    to.update(arg);

    }

    });

    }

    展开全文
  • // 20 闭包,closure 闭包闭包就是能够读取其他函数内部变量的函数 var baz; (function () { var foo = 10; var bar = 2; baz = function () { return foo * bar; } })(); console.log(baz()); // 20 闭包代码块 ...

    匿名函数

    (function () {

    var foo = 10;

    var bar = 2;

    console.log(foo*bar);

    })(); // 20

    带参数的匿名函数

    (function (foo,bar) {

    console.log(foo*bar);

    })(10,2); // 20

    var baz = (function (foo,bar) {

    return foo * bar;

    })(10,2);

    console.log(baz); // 20

    闭包,closure 闭包,闭包就是能够读取其他函数内部变量的函数

    var baz;

    (function () {

    var foo = 10;

    var bar = 2;

    baz = function () {

    return foo * bar;

    }

    })();

    console.log(baz()); // 20

    闭包代码块

    能理解下面的几个代码块,就算能理解闭包了。闭包可以读取其他函数内部变量。var that = this;就是精髓。

    // 代码块一

    var name = "The Window";

    var object = {

    name : "My Object",

    getNameFunc : function(){

    return function(){

    return this.name; // this是匿名函数

    };

    }

    };

    console.log(object.getNameFunc()()); // undefined

    console.log(object.getNameFunc().call(object)); // My Object

    // 代码块二

    var name = "The Window";

    var object = {

    name : "My Object",

    getNameFunc : function(){

    var that = this;

    return function(){ // 闭包

    return that.name;

    };

    }

    };

    console.log(object.getNameFunc()()); // My Object

    // 代码块三

    var name = "The Window";

    var object = {

    name : "My Object",

    getNameFunc : function(){

    return function(){

    return name;

    };

    }

    };

    console.log(object.getNameFunc()()); // The Window

    // 代码块四

    var name = "The Window";

    var object = {

    name : "My Object",

    getNameFunc : function(){

    return this.name; // this是object

    }

    };

    console.log(object.getNameFunc()); // My Object

    方法论总结:可以针对关键点,进行深入探讨。百度搜索相关的博文或百科探索。

    展开全文
  • [Java教程]javscript闭包的准备工作0 2016-08-27 11:00:03作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理。今天这篇文章对JavaScript作用域和作用域链作...

    [Java教程]javscript闭包的准备工作

    0 2016-08-27 11:00:03

    作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理。今天这篇文章对JavaScript作用域和作用域链作简单的介绍,希望能帮助大家更好的学习JavaScript。

    JavaScript作用域

    任何程序设计语言都有作用域的概念,简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在JavaScript中,变量的作用域有全局作用域和局部作用域两种。

    1.  全局作用域(Global Scope)

    在代码中任何地方都能访问到的对象拥有全局作用域,一般来说以下几种情形拥有全局作用域:

    (1)最外层函数和在最外层函数外面定义的变量拥有全局作用域,例如:var authorName="风之羽翼";function her(){ var blogName="风"; function innerSay(){ alert(blogName); } innerSay();}alert(authorName); // 风之羽翼alert(blogName); // 脚本错误doSomething(); // 风innerSay() // 脚本错误

    (2)所有末定义直接赋值的变量自动声明为拥有全局作用域,例如:function doSomething(){ var authorName="风之羽翼"; blogName="风"; alert(authorName);}doSomething(); // 风之羽翼alert(blogName); / 风alert(authorName); // 脚本错误

    变量blogName拥有全局作用域,而authorName在函数外部无法访问到。

    3)所有window对象的属性拥有全局作用域

    一般情况下,window对象的内置属性都拥有全局作用域,例如window.name、window.location、window.top等等。

    2.  局部作用域(Local Scope):

    和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所有在一些地方也会看到有人把这种作用域称为函数作用域,例如下列代码中的blogName和函数innerSay都只拥有局部作用域。function doSomething(){ var blogName="风之羽翼"; function innerSay(){ alert(blogName); } innerSay();}alert(blogName); // 脚本错误innerSay(); // 脚本错误

    作用域链(Scope Chain)

    尽管javascript中不存在大括号级的作用域。但是它有函数作用域啊!!,也就是说在函数内定义的变量在该函数外是不可见的。但在if,for等代码块中定义的变量,在外面是可见的。

    当一个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象填充。例如定义下面这样一个函数:function her(num1,num2) { var sum = num1 + num2; return sum;}

    在函数her创建时,它的作用域链中会填入一个全局对象,该全局对象包含了所有全局变量例如window.....

    函数her的作用域将会在执行时用到。例如执行如下代码:var shel = her(5,10); // 15

    执行此函数时会创建一个称为“运行期上下文(execution context)”的内部对象,运行期上下文定义了函数执行时的环境。每个运行期上下文都有自己的作用域链,用于标识符解析,当运行期上下文被创建时,而它的作用域链初始化为当前运行函数的[[Scope]]所包含的对象。这些值按照它们出现在函数中的顺序被复制到运行期上下文的作用域链中。它们共同组成了一个新的对象,叫“活动对象(activation object)”,该对象包含了函数的所有局部变量、命名参数、参数集合以及this,然后此对象会被推入作用域链的前端,当运行期上下文被销毁,活动对象也随之销毁。

    简单的理解一下:var a = 1;function her(){ var b = 2; function son(){ var c = 3; return a + b + c; } return son();}her() // 6

    在上面的一个例子中,我们的函数her()中定义了另一个函数son(),那么son()中可访问的变量及来自他本身的作用域,也有来自父级作用域里的变量,这就形成了一条‘’链‘’,也就是作用域链,该链的长度或深度取决于我们的需要。

    在函数执行过程中,没遇到一个变量,都会经历一次标识符解析过程以决定从哪里获取和存储数据。该过程从作用域链头部,也就是从活动对象开始搜索,查找同名的标识符,如果找到了就使用这个标识符对应的变量,如果没找到继续搜索作用域链中的下一个对象,如果搜索完所有对象都未找到,则认为该标识符未定义。函数执行过程中,每个标识符都要经历这样的搜索过程。

    也就是说,上述代码中return a+b+c 在son()中没有a,b那么她便会向上一层her()中找a,b,若her()中也找不到再向上一层找直到找到最外层window,如果还是找不到该变量就会返回undefined;

    作用域链和代码优化:

    从作用域链的结构可以看出,在运行期上下文的作用域链中,标识符所在的位置越深,读写速度就会越慢。如上图所示,因为全局变量总是存在于运行期上下文作用域链的最末端,因此在标识符解析的时候,查找全局变量是最慢的。所以,在编写代码的时候应尽量少使用全局变量,尽可能使用局部变量。一个好的经验法则是:如果一个跨作用域的对象被引用了一次以上,则先把它存储到局部变量里再使用。例如下面的代码:function changeColor(){ document.getElementById("btnChange").οnclick=function(){ document.getElementById("targetCanvas").style.backgroundColor="red"; };}

    这个函数引用了两次全局变量document,查找该变量必须遍历整个作用域链,直到最后在全局对象中才能找到。这段代码可以重写如下:function changeColor(){ var doc=document; doc.getElementById("btnChange").οnclick=function(){ doc.getElementById("targetCanvas").style.backgroundColor="red"; };}

    这段代码比较简单,重写后不会显示出巨大的性能提升,但是如果程序中有大量的全局变量被从反复访问,那么重写后的代码性能会有显著改善。

    改变作用域链:

    函数每次执行时对应的运行期上下文都是独一无二的,所以多次调用同一个函数就会导致创建多个运行期上下文,当函数执行完毕,执行上下文会被销毁。每一个运行期上下文都和一个作用域链关联。一般情况下,在运行期上下文运行的过程中,其作用域链只会被 with 语句和 catch 语句影响。

    with语句是对象的快捷应用方式,用来避免书写重复代码。例如:function initUI(){ with(document){ var bd=body, links=getElementsByTagName("a"), i=0, len=links.length; while(i < len){ update(links[i++]); } getElementById("btnInit").οnclick=function(){ doSomething(); }; }}

    这里使用width语句来避免多次书写document,看上去更高效,实际上产生了性能问题。

    当代码运行到with语句时,运行期上下文的作用域链临时被改变了。一个新的可变对象被创建,它包含了参数指定的对象的所有属性。这个对象将被推入作用域链的头部,这意味着函数的所有局部变量现在处于第二个作用域链对象中,因此访问代价更高了。

    此在程序中应避免使用with语句,在这个例子中,只要简单的把document存储在一个局部变量中就可以提升性能。

    另外一个会改变作用域链的是try-catch语句中的catch语句。当try代码块中发生错误时,执行过程会跳转到catch语句,然后把异常对象推入一个可变对象并置于作用域的头部。在catch代码块内部,函数的所有局部变量将会被放在第二个作用域链对象中。示例代码:try{ doSomething();}catch(ex){ alert(ex.message); //作用域链在此处改变}

    请注意,一旦catch语句执行完毕,作用域链机会返回到之前的状态。try-catch语句在代码调试和异常处理中非常有用,因此不建议完全避免。你可以通过优化代码来减少catch语句对性能的影响。一个很好的模式是将错误委托给一个函数处理,例如:try{ doSomething();}catch(ex){ handleError(ex); //委托给处理器方法}

    优化后的代码,handleError方法是catch子句中唯一执行的代码。该函数接收异常对象作为参数,这样你可以更加灵活和统一的处理错误。由于只执行一条语句,且没有局部变量的访问,作用域链的临时改变就不会影响代码性能了。

    bc91bb04e6e9c61e24c974e4440db8f2.gif

    本文网址:http://www.shaoqun.com/a/248898.html

    *特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:admin@shaoqun.com。

    ip

    0

    展开全文
  • 对于迭代器模式,就是我们在集合中用到的迭代器一样,我们要做的就是实现java中的Iterator接口所用到的方法即可。 这种模式分为四部分: 自己的迭代器接口, 迭代器接口的实现类, 自己创建的集合接口, 集合接口的实现类 ...
  • java闭包运用 实现方法传递

    千次阅读 2011-07-26 18:29:30
    写了一个测试java闭包的实例,在事件监听中用得比较多的设计模式!定义一个接口,通过接口来传递方法体/** * @author yaohw * */ public interface Action{ public void excute(Object arg); }
  • 看完上一篇文章之后, 相信大家对闭包代理有了个初步认识. 如果没看上一篇文章, 最好看一下, 闭包代理模式-初创篇 因为闭包代理是针对函数式接口实例的代理, 而函数式接口实例可以相互转化, 非常灵活, 这就使得闭包...
  • 闭包

    2019-11-20 11:23:28
    一些不支持函数式编程的语言中也能支持闭包(如java8之前的匿名内部类)。 在看过的对于闭包的定义中,个人觉得比较清晰的是在《JavaScript高级程序设计》这本书中看到的。具体定义如下: 闭包是指有权访问另一个...
  • 今天看《Javascript高级程序设计》一书,其中对闭包下了一个定义: 闭包是词法表示包括不必计算的变量的函数。(原书第56页) 还给了一个简单的样例: <pre name="code" class="js...
  • 抽象工厂模式工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,...
  • 跨越边界:闭包

    2020-03-04 12:05:21
    其他一些人则认为闭包将引发新一轮模式设计的潮流。闭包是可以用作函数参数和方法参数的代码块。一直以来,这种编程结构都是一些语言(如 Lisp、Smalltalk 和 Haskell)的重要组成部分。尽管一些颇具竞争力的语言...
  • java常见设计模式

    2018-08-26 11:40:00
    工厂模式 普通工厂模式,就是建立一个工厂类,...工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,...
  • 1. 前言 2. 【译】lambda表达式和闭包的区别 3. 历史考据 ...而这种答案是不能让人满意的,因为这样的回答会让人感觉闭包是编程语言设计设计出来的一个很蠢的东西。 例如这种类型的回答: - 闭包能实现...
  • 闭包(Clousure)

    2020-12-31 20:06:03
    一些不支持函数式编程的语言中也能支持闭包(如java8之前的匿名内部类)。 在看过的对于闭包的定义中,个人觉得比较清晰的是在《JavaScript高级程序设计》这本书中看到的。具体定义如下: 闭包是指有权访问
  • C#中的闭包

    2018-08-28 19:35:20
    一些不支持函数式编程的语言中也能支持闭包(如java8之前的匿名内部类)。 在看过的对于闭包的定义中,个人觉得比较清晰的是在《JavaScript高级程序设计》这本书中看到的。具体定义如下: 闭包是指有权访问另一个...
  • 其实最开始, 我是在用 java swing 做一个 endpoint-io-transfer 的应用工具(一个用于从citrix下载文件的工具). 页面里面有几个按钮, 点击按钮执行逻辑功能, 相关代码大概是这样: private JComponent getToolBar() { ...
  • 理解C#中的闭包

    2018-08-25 20:41:00
    一些不支持函数式编程的语言中也能支持闭包(如java8之前的匿名内部类)。 在看过的对于闭包的定义中,个人觉得比较清晰的是在《JavaScript高级程序设计》这本书中看到的。具体定义如下: 闭包是指有权访问另一个...
  • 但今天要说的是 主流语言都有闭包 如:C#、Java、C++、swift、Go,一些非主流语言也是有闭包的 所以 闭包 并不是某个语言特有,闭包是跨越语言的设计 本文代码以C#为主 得心应手 一个闭包就是一个“捕获”了其生成...
  • Android Groovy(六) 闭包

    2019-10-08 10:19:47
    首先申明下,本文为笔者学习...闭包是Groovy的特性之一,类似于Java中的匿名内部类,但功能更加强大。 1. 闭包应用 一般用法 def filter(array, block) { for (val in array) { block(val) } } iarray ...
  • 1.抽象工厂模式工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建...
  • 上一篇文章(http://www.cnblogs.com/liaoweipeng/p/5768197.html)讲了简单工厂模式,但是简单工厂模式存在一定的问题,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包-开放原则,所以,从设计角度考虑,有...
  • 工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,...
  • 对枚举类型印象大多来自于C 语言,在 C 语言中,枚举类型是一个 Hard...笔者比较赞同引入枚举,作为一门通用的静态编程语言,应该是海纳百川的(因此笔者赞成闭包进入Java7 ),多途径实现功能。 如果您不了解枚...
  • 工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就 用到工厂方法模式,创建一个工厂接口和创建多个工厂实现类,这样一旦需要增加新的功能, 直接增加新的工厂类就可以了,不需要...
  • Java设计模式之-抽象工厂模式工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象...
  • ruby 闭包(转)

    2010-07-20 17:39:11
    关于闭包这个问题,Java 爱好者们现在陷入了类似的争论中。一些人认为闭包带给编程语言的额外复杂性并不划算。他们的论点是:为了闭包带来的一点点便利而打破原有语法糖的简洁性非常不值得。其他一些人则认为闭包将...

空空如也

空空如也

1 2 3 4 5 ... 19
收藏数 372
精华内容 148
热门标签
关键字:

java闭包设计

java 订阅