2010-06-24 80 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();}... 

你不能做類似的東西這與字符串,如實現一個接口或添加一個方法到一個子類,因爲該字符串類是最終的。