b********r 发帖数: 118 | 1 java experience也5years+ 被hm问了这个问题不知道
人家让我google一下 下次meet再聊 回来google 居然没找到
他说是类似inner class的东西 版上大牛提示一下? 可能我拼写错了
多谢 |
s******5 发帖数: 673 | 2 Not sure if this is what you are looking for..
(it is called closure)
http://gioorgi.com/2010/closure-in-java-fast-and-nice/
but it def does something with java inner class..
【在 b********r 的大作中提到】![](/moin_static193/solenoid/img/up.png) : java experience也5years+ 被hm问了这个问题不知道 : 人家让我google一下 下次meet再聊 回来google 居然没找到 : 他说是类似inner class的东西 版上大牛提示一下? 可能我拼写错了 : 多谢
|
s******5 发帖数: 673 | 3
Plus:
http://stackoverflow.com/questions/355167/how-are-anonymous-inner-classes-used-in-java/355382#355382
【在 b********r 的大作中提到】![](/moin_static193/solenoid/img/up.png) : java experience也5years+ 被hm问了这个问题不知道 : 人家让我google一下 下次meet再聊 回来google 居然没找到 : 他说是类似inner class的东西 版上大牛提示一下? 可能我拼写错了 : 多谢
|
y*********e 发帖数: 518 | 4 感觉对方是在问 Closure。
这个是 Java 对 Lambda 表达式的实现。Java 7 已经确定在语法上支持这个。
Java 6或者以前的版本只能靠 interface + anonymous class 来实现。
若是做过 functional programming(比如haskell),应该对 Lamdba 表达
式比较熟悉。
从C++的角度来看,就是 function pointer,但是它是 Strongly Typed。
举例代码来说明。假设要对二叉树遍历,代码很好写,比如:
void inOrder(Tree tree) {
if (tree != null) {
inOrder(tree.getLeft());
System.out.println(tree.getValue());
inOrder(tree.getRight());
}
}
但是如上的函数只是把Node的值打印到终端。若是要变得generic一点,要遍历的
过程中,能引入一个函数,对每一个Node执行这个函数,该多好。这样就引入了一
个概念:能否把函数当做一个对象,传递入inOrder函数呢?
可以用如下的代码调用inOrder函数(Java 7的语法比较雷):
inOrder(tree,
#(Tree tree)(System.out.println(tree.getValue())
);
inOrder的定义要修改成:
void inOrder(Tree tree, #()(Tree tree));
一些示范代码:
之一:
#int(int x) fc; // 声明一个 variable
fc = #(int x)(x + 1); // 第一个括号是引入参数,第二个括号是代码
int x = fc(4); // 4加1,得5,然后赋值给x
之二:
int y = #(int x)(x + 1).(3); // y = 3 + 1
住:如上的语法还不是final版本。。在Java 7出来之前一切都会有变动。
所以Closure其实包含2个部分:1是把每个函数当作对象,2是一个简化的匿名函数
的语法。
在Java 6的话,就用interface+匿名类来实现了:
interface Closure { public void invoke(T t); }
void inOrder(Tree tree, Closure closure) {
if (tree != null) {
inOrder(tree.getLeft());
closure.invoke(tree);
inOrder(tree.getRight());
}
}
执行的代码如此:
inOrder(tree, new Closure() {
public void invoke(Tree tree) {
System.out.println(tree.getValue());
}
});
Java的最初的设计,即所有函数必须属于一个对象,导致了对拉姆达表达式的支持
非常困难。写出来的代码让人非常雷。
相比之下,C#的语言就简介多了:
delegate void TraversalAction(Tree tree); // 一个函数模板
void InOrder(Tree tree, TraversalAction action) {
if (tree != null) {
InOrder(tree.getLeft());
action(tree); // 执行该函数
InOrder(tree.getRight());
}
}
执行的代码如此:
InOrder(tree,
{ tree => Console.WriteLine(tree) } // 一个代码片段
);
也可以这么执行:
// 把一个代码片段存放入variable中
var func = (TraversalAction) delegate (Tree tree) {
tree => Console.WriteLine(tree);
};
// 把func传入函数InOrder作为一个参数
InOrder(tree, func);
总结一点:拉姆达表达式就是把一个代码片段或者一个函数当作对象。该对象
可以赋值给variable,也可以作为函数的引入参数。
若是C/C++语言,最经典的例子就是qsort函数:
void qsort (
void * base,
size_t num,
size_t size,
int (*comparator)(const void*, const void*)
);
第四个参数,就是一个function pointer。在调用qsort函数的时候,可以
把另外一个函数当作参数直接调入qsort。
【在 b********r 的大作中提到】![](/moin_static193/solenoid/img/up.png) : java experience也5years+ 被hm问了这个问题不知道 : 人家让我google一下 下次meet再聊 回来google 居然没找到 : 他说是类似inner class的东西 版上大牛提示一下? 可能我拼写错了 : 多谢
|
c*******s 发帖数: 1555 | 5 niu
【在 y*********e 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 感觉对方是在问 Closure。 : 这个是 Java 对 Lambda 表达式的实现。Java 7 已经确定在语法上支持这个。 : Java 6或者以前的版本只能靠 interface + anonymous class 来实现。 : 若是做过 functional programming(比如haskell),应该对 Lamdba 表达 : 式比较熟悉。 : 从C++的角度来看,就是 function pointer,但是它是 Strongly Typed。 : 举例代码来说明。假设要对二叉树遍历,代码很好写,比如: : void inOrder(Tree tree) { : if (tree != null) { : inOrder(tree.getLeft());
|
f*******h 发帖数: 53 | 6 Niu, thanks.
【在 y*********e 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 感觉对方是在问 Closure。 : 这个是 Java 对 Lambda 表达式的实现。Java 7 已经确定在语法上支持这个。 : Java 6或者以前的版本只能靠 interface + anonymous class 来实现。 : 若是做过 functional programming(比如haskell),应该对 Lamdba 表达 : 式比较熟悉。 : 从C++的角度来看,就是 function pointer,但是它是 Strongly Typed。 : 举例代码来说明。假设要对二叉树遍历,代码很好写,比如: : void inOrder(Tree tree) { : if (tree != null) { : inOrder(tree.getLeft());
|
d**e 发帖数: 6098 | 7 真是牛得一塌糊涂
【在 y*********e 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 感觉对方是在问 Closure。 : 这个是 Java 对 Lambda 表达式的实现。Java 7 已经确定在语法上支持这个。 : Java 6或者以前的版本只能靠 interface + anonymous class 来实现。 : 若是做过 functional programming(比如haskell),应该对 Lamdba 表达 : 式比较熟悉。 : 从C++的角度来看,就是 function pointer,但是它是 Strongly Typed。 : 举例代码来说明。假设要对二叉树遍历,代码很好写,比如: : void inOrder(Tree tree) { : if (tree != null) { : inOrder(tree.getLeft());
|
c*****h 发帖数: 166 | 8 这个apache commons包里面有 functor里面的一种 又看了下 很像visitor pattern
呢 |
c*****h 发帖数: 166 | |
y*********e 发帖数: 518 | 10 Apache Common里面那个提供的是一系列的interface还有static的函数来做辅助。
真正的Closure还要提供语法上的支持。要提供一种简单的方法,能够把一个代码片段
当作参数带入函数。
比如,你给的链接里面的 Ruby 的示例代码:
def highPaid(emps)
threshold = 150
return emps.select { |e| e.salary > threshold }
end
这里的代码片段 |e| e.salary > threshold 其实会被编译成一个匿名函数。输入 e,返回
e.salary > threshold。所以输入类型是Employee,输出是Boolean。
但是Java 6在语法上就不支持,非要创建一个interface,然后new一个新的对象,把对
象当作参数带入select函数。麻烦之级。
除此之外,还要求编译器能自动鉴别数据类型 (Type Inference)。比如,我写一个匿
名函数,x => x + 1,这个 x 可以是 int,也可以是 long,还可以是 double。对于
支持generic的语言来说,这个可以做成一个generic:
T foo(T t) {
return t + 1;
}
但是Java的generic用的是type erase,到了Java bytecode所有的Type信息都消失了,
变成了Object。也即,上例的Java Generic函数会被编译成(如果编译成功的话):
Object foo(Object t) {
return t + 1; // 所以编译会失败 -___-,因为Object不支持操作符+
}
这就造成了Java 7对Closure支持的困难,编译器无法做到Type Inference。写Closure
的时候还必须指明数据类型。要写成大概这样的形式: int x => x + 1。 |
T*********g 发帖数: 496 | 11 是问闭包呢。
【在 b********r 的大作中提到】![](/moin_static193/solenoid/img/up.png) : java experience也5years+ 被hm问了这个问题不知道 : 人家让我google一下 下次meet再聊 回来google 居然没找到 : 他说是类似inner class的东西 版上大牛提示一下? 可能我拼写错了 : 多谢
|
h**********d 发帖数: 4313 | 12 强,学习了
【在 y*********e 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 感觉对方是在问 Closure。 : 这个是 Java 对 Lambda 表达式的实现。Java 7 已经确定在语法上支持这个。 : Java 6或者以前的版本只能靠 interface + anonymous class 来实现。 : 若是做过 functional programming(比如haskell),应该对 Lamdba 表达 : 式比较熟悉。 : 从C++的角度来看,就是 function pointer,但是它是 Strongly Typed。 : 举例代码来说明。假设要对二叉树遍历,代码很好写,比如: : void inOrder(Tree tree) { : if (tree != null) { : inOrder(tree.getLeft());
|