2012-01-17 10 views
13

Khi nào tôi nên chọn cái này hơn cái kia? Mục đích của phương pháp được hiển thị bên dưới là gì?Sự khác biệt giữa "new A()" và "A.newInstance()" là gì?

class A { 
    public static A newInstance() { 
     A a = new A(); 
     return a ; 
    } 
} 

Ai đó có thể giải thích cho tôi sự khác biệt giữa hai cuộc gọi này?

+1

Thông thường, A.newInstance được sử dụng cho mẫu thiết kế singleton. –

Trả lời

16

newInstance() thường được sử dụng như một cách để tạo một đối tượng mà không cần trực tiếp gọi constructor mặc định của đối tượng. Ví dụ, nó thường được sử dụng để thực hiện một thiết kế mẫu Singleton:

public class Singleton { 
    private static final Singleton instance = null; 

    // make the class private to prevent direct instantiation. 
    // this forces clients to call newInstance(), which will 
    // ensure the class' Singleton property. 
    private Singleton() { } 

    public static Singleton newInstance() { 
     // if instance is null, then instantiate the object by calling 
     // the default constructor (this is ok since we are calling it from 
     // within the class) 
     if (instance == null) { 
      instance = new Singleton(); 
     } 
     return instance; 
    } 
} 

Trong trường hợp này, các lập trình viên buộc khách hàng để gọi newInstance() để lấy một thể hiện của lớp. Điều này quan trọng bởi vì chỉ đơn giản là cung cấp một hàm tạo mặc định sẽ cho phép máy khách truy cập vào nhiều phiên bản của lớp (mà đi ngược lại thuộc tính Singleton).

Trong trường hợp Fragment s, việc cung cấp phương pháp nhà máy tĩnh newInstance() là thực tiễn tốt vì chúng tôi thường muốn thêm đối số khởi tạo cho đối tượng mới được tạo. Thay vì yêu cầu trình khách gọi hàm tạo mặc định và tự đặt chính các tham số đoạn, chúng tôi có thể cung cấp phương thức newInstance() thực hiện điều này cho chúng. Ví dụ,

public static MyFragment newInstance(int index) { 
    MyFragment f = new MyFragment(); 
    Bundle args = new Bundle(); 
    args.putInt("index", index); 
    f.setArguments(args); 
    return f; 
} 

Nhìn chung, trong khi chênh lệch giữa hai chủ yếu là chỉ là vấn đề thiết kế, sự khác biệt này là thực sự quan trọng vì nó cung cấp một mức độ trừu tượng và làm cho mã dễ dàng hơn rất nhiều để hiểu được.

+0

tuyệt vời, nó làm cho tôi suy nghĩ dễ dàng hơn, cảm ơn nhiều – rex

+0

Hm, nhưng bạn không thể quấn cùng một mã trong một hàm tạo? 'lớp công khai MyFragment { MyFragment (Bundle args) {this.setArguments (args) ...} MyFragment (int index) {Bundle args = new Bundle(); args.putInt (...); này (args)} ' – Karsten

+0

bạn đang cố gắng thay đổi tham chiếu của biến cuối cùng" instance ", lỗi của nó, phải không? –

1

Trong ví dụ của bạn, chúng tương đương nhau và không có lý do thực sự nào để chọn cái kia. Tuy nhiên, sử dụng newInstance thường được sử dụng nếu để thực hiện một số khởi tạo trước khi giao lại một thể hiện của lớp. Nếu mỗi khi bạn yêu cầu một cá thể mới của lớp bằng cách gọi hàm tạo của nó, bạn sẽ thiết lập một loạt các biến mẫu trước khi bạn có thể sử dụng đối tượng, thì sẽ có ý nghĩa hơn khi có phương thức newInstance thực hiện khởi tạo đó và trả về cho bạn một đối tượng sẵn sàng sử dụng.

Ví dụ: Activity s và Fragment s không được khởi tạo trong các nhà thầu của chúng. Thay vào đó, chúng thường được khởi tạo trong quá trình onCreate. Do đó, thực hành phổ biến cho phương thức newInstance chấp nhận bất kỳ tham số nào mà đối tượng sẽ cần sử dụng trong quá trình khởi tạo và nó lưu trữ chúng trong một Gói mà đối tượng có thể đọc từ sau này. Một ví dụ về điều này có thể được nhìn thấy ở đây:

Sample class with newInstance method

0

new() là một từ khóa dùng để tạo ra một đối tượng và nó có thể được sử dụng trong khi chúng ta biết tên lớp
new instance() Là một phương pháp sử dụng để tạo ra một đối tượng và nó có thể được sử dụng khi chúng ta không biết về tên lớp