2010-06-24 83 views
-3

我遇到了一个奇怪的函数调用(如下所示):奇怪的函数调用

addData("abc", "abc" { 
     public boolean isDataCorrect() { 
      return true; 
     } 
     }); 

addData签名

public void addData(String a, String b); 

谁能解释什么大括号中的代码在做什么?而且它甚至是如何工作的?

+0

是在一个枚举? – Dan 2010-06-24 23:11:32

+1

里面的枚举是什么? – chitresh 2010-06-24 23:14:46

+1

为什么发布不能编译的代码?这是对这里的参与者的不敬。 – 2010-06-24 23:33:12

回答

4

这不会编译。

也许你看到哪些不再存在。

例如假设addData方法使用接收String a , OtherClass b后来,OtherClass被串并在自动重构取代,也来了,是这样的:

// BEFORE 
addData("abc", new AbcValidator("abc"){ 
     public boolan isDataCorrect(){ 
      return true; 
     } 
}); 
addData(String a, AbcValidator b) { 
} 

重构后,有人(可能是一个糟糕的重构工具)认为可以使用原始字符串。

// AFTER: 
addData("abc", "abc"{ 
     public boolan isDataCorrect(){ 
      return true; 
     } 
}); 
addData(String a, AbcValidator b) { 
} 

当你编译并运行它,它甚至不进行编译,但因为它是运行前,运行脚本采用以前的版本(使用AbcValidator的一个),看起来像它的工作,但不是这样。

几乎不可能猜测你的办公桌正在发生什么,但是不会犯错,那是不会发生的。

探讨它执行以下操作:

A)创建新的目录和一个Java “Hey.java” 具有以下内容:

class Hey{ 
    public static void main(String [] args) { 
     addData("abc", "abc" { 
      public boolean isDataCorrect() { 
       return true; 
      } 
     }); 
    } 
    public void addData(String a, String b){} 
} 

B)编译该文件,优选地从命令行:javac Hey.java

你会看到它不起作用。

+0

是的你是对的。但是,你能否进一步解释一件事。代码在评论“//之前”addData需要一个对象作为它的第二个参数,{}里面的代码是做什么的。我的意思是你只需要一个对象,所以你可以调用一个构造函数。为什么你需要额外的代码行。 – chitresh 2010-06-24 23:28:14

+0

他正在扩展AbcValidator接口(未显示)。我已经发布了一个(略)更加扩展的版本。 – 2010-06-24 23:30:14

+1

这是一个匿名的内部类。它通常用于创建另一个类的内联子类。这就是Java多年前发明的用于替代关闭的东西,它们实际上是关闭的,但非常冗长。他们非常方便地提供新的类实现。 – OscarRyz 2010-06-24 23:44:02

1

你的例子不编译。我知道,你可以做这样的最接近的是一个初始化块,像

public void addData(Map ...) 
addData(new HashMap(){ { put("A", "B");}} 

或声明的匿名类时被调用的函数:

public interface Adder { public boolean isDataCorrect(); } 
public void addData(Adder ...) 
addData(new Adder(){ public boolean isDataCorrect();}... 

你不能做类似的东西这与字符串,如实现一个接口或添加一个方法到一个子类,因为该字符串类是最终的。