2012-12-28 65 views
8

可能重複:
Why does this() and super() have to be the first statement in a constructor?「構造函數調用必須在構造函數中的第一條語句」的問題在Java中

我想有構造函數鏈中的Java。例如,對於第一個構造函數,我有一個字符串作爲參數,並在從參數字符串創建對象時調用第二個構造函數。

public class IMethodFinder { 
    public IMethodFinder(String projectName, String methodName, 
     int numberOfParameters) { 
     IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); 
     IJavaProject javaProject = JavaCore.create(project); 
     this(javaProject, methodName, numberOfParameters); 
    } 

    public IMethodFinder(IJavaProject javaProject, String methodName, 
     int numberOfParameters) { 
     ... 
    } 
} 

但是,我得到一個錯誤「構造函數調用必須是構造函數中的第一個語句」錯誤。

enter image description here

我提出,在兩個構造之間共享的公共代碼,但我不知道這是爲了繞過這個問題的唯一解決方案。

public class IMethodFinder { 
    public IMethodFinder(IJavaProject javaProject, String methodName, 
      int numberOfParameters) { 
     dosomething(javaProject, methodName, numberOfParameters); 
    } 

    public IMethodFinder(String projectName, String methodName, 
      int numberOfParameters) { 
     IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); 
     IJavaProject javaProject = JavaCore.create(project); 
     dosomething(javaProject, methodName, numberOfParameters); 
    } 

    private void dosomething(IJavaProject javaProject, String methodName, 
      int numberOfParameters) 
    { 
     ... 
    } 

} 
  • 爲什麼Java的要求構造函數調用作爲第一條語句?這個要求背後的想法是什麼?
  • 什麼是Java的慣例爲我的情況?調用常用方法是一個好方法嗎?
+2

是,調用一個'的init( )'從你的構造函數中的函數是很常見的。 –

+1

您可以將第一個構造函數的主體重寫爲:'this(JavaCore.create(ResourcesPlugin.getWorkspace()。getRoot()。getProject(projectName)),methodName,numberOfParameters);' – Alex

回答

14

沒有深層原因的Java不能擴展到允許不構造之前訪問this語句。但是,這會增加語言的複雜性並在使用時隱藏代碼(特別是當您認爲調用可能是隱含的時)。

通常你想保持構造函數儘可能簡單。 init()方法是一個壞主意,因爲它們阻止使用final。看起來,代碼正在訪問一個可變的靜態,這是一個非常糟糕的主意。

針對您的特殊的代碼,你可以寫:

public IMethodFinder(String projectName, String methodName, 
     int numberOfParameters) { 
     this(
      JavaCore.create(
       ResourcesPlugin.getWorkspace().getRoot().getProject(projectName) 
      ), 
      methodName, 
      numberOfParameters 
     ); 
    } 

一個更普遍的黑客是在調用構造函數中調用靜態方法:

public class IMethodFinder { 
    public IMethodFinder(String projectName, String methodName, 
     int numberOfParameters) { 
     this(createProject(projectName), methodName, numberOfParameters); 
    } 

    public IMethodFinder(IJavaProject javaProject, String methodName, 
     int numberOfParameters) { 
     ... 
    } 

    private static IJavaProject createProject(String projectName) { 
     IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); 
     IJavaProject javaProject = JavaCore.create(project); 
     return javaProject; 
    } 
} 
+3

+1 for「There is no爲什麼Java無法擴展到允許在構造函數之前不訪問它的語句的內在原因「。 – Pacerier

2

解決方案1:您的構造者應該有一個更有針對性的流程來避免使用共同的init。通常一個構造函數會更基本,構造一個完整的有效對象,然後外部構造函數可以對此進行修飾。

解決方案2:使用靜態工廠方法通常是很好的做法,例如可以處理您需要的預處理。這看起來像是這種模式的一個很好的用例。

解決方案3:而不是一個普通的init方法只是靜態方法,爲你做孤立的預處理。例如myField = processInputField(myField)。常見的init方法對最終字段的效果很差,這是一個更糟糕的實踐 - 更重要的是,建設者應該完成構建的全部工作。

1

看到this answer你的第一個問題 爲你的第二個問題 - 是其相對接受使用某種init()方法對這些案件

相關問題