2012-12-28 3 views
8

thể trùng lặp:
Why does this() and super() have to be the first statement in a constructor?"gọi Constructor phải là tuyên bố đầu tiên trong một constructor" vấn đề trong Java

Tôi muốn có chuỗi constructor trong Java. Ví dụ, với hàm tạo đầu tiên, tôi có một chuỗi như một tham số và gọi hàm tạo thứ hai khi tôi tạo một đối tượng từ chuỗi tham số.

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) { 
     ... 
    } 
} 

Tuy nhiên, tôi gặp lỗi "Lỗi xây dựng cuộc gọi phải là câu lệnh đầu tiên trong hàm tạo".

enter image description here

tôi đã thực hiện một mã phổ biến mà được chia sẻ giữa hai nhà thầu, nhưng tôi không chắc chắn đây là giải pháp duy nhất để vượt qua vấn đề này.

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) 
    { 
     ... 
    } 

} 
  • Tại sao Java yêu cầu cuộc gọi constructor là tuyên bố đầu tiên? Ý tưởng đằng sau yêu cầu này là gì?
  • Quy ước của Java đối với trường hợp của tôi là gì? Là phương pháp phổ biến gọi là một cách tốt để đi?
+2

có, gọi một 'init () 'Hàm từ hàm tạo của bạn là phổ biến. –

+1

Bạn chỉ có thể viết lại phần thân của hàm tạo đầu tiên như sau: 'this (JavaCore.create (ResourcesPlugin.getWorkspace(). GetRoot(). GetProject (projectName)), methodName, numberOfParameters); ' – Alex

Trả lời

14

Không có lý do nội tại sao Java không thể được mở rộng để cho phép báo cáo mà không truy cập this trước khi các nhà xây dựng. Tuy nhiên, điều đó sẽ thêm vào sự phức tạp của ngôn ngữ và làm mờ mã khi được sử dụng (đặc biệt khi bạn xem xét cuộc gọi có thể ngầm).

Nói chung bạn muốn giữ các nhà thầu càng đơn giản càng tốt. init() phương pháp là một ý tưởng tồi khi chúng ngăn chặn việc sử dụng final. Có vẻ như mã đang truy cập vào một tĩnh có thể thay đổi được, đó là một ý tưởng thực sự tồi.

Đối với mã cụ thể của bạn, bạn có thể viết:

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

Một tổng quát hơn Hack là để gọi một phương thức tĩnh trong lời kêu gọi các nhà xây dựng:

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 cho" không có lý do tại sao tại sao Java không thể được mở rộng để cho phép các câu lệnh không truy cập được điều này trước nhà xây dựng ". – Pacerier

2

Giải pháp 1: Các nhà thầu của bạn phải có luồng hướng đạo tốt hơn để tránh sử dụng chung init. Khá thường xuyên một nhà xây dựng sẽ được cơ bản hơn và xây dựng một đối tượng hoàn chỉnh hợp lệ, sau đó các nhà xây dựng bên ngoài có thể trang trí này.

Giải pháp 2: Thực tiễn tốt là sử dụng phương pháp nhà máy tĩnh, ví dụ: có thể xử lý tiền xử lý bạn cần tại đây. Điều này trông giống như một trường hợp sử dụng tốt cho mẫu này.

Giải pháp 3: Thay vì phương thức init phổ biến, chỉ có các phương pháp tĩnh làm tiền xử lý riêng biệt cho bạn. ví dụ. myField = processInputField(myField). Các phương thức phổ biến init chơi rất kém với các trường cuối cùng là một lý do mạnh hơn chúng là thực hành không tốt - về cơ bản, có, các nhà xây dựng nên làm công việc hoàn chỉnh của việc xây dựng.

1

thấy this answer cho câu hỏi 1 của bạn như đối với câu hỏi thứ 2 của bạn - có của nó tương đối chấp nhận sử dụng một số loại init() phương pháp cho những trường hợp này