2011-10-31 18 views
8

Tôi đang thực hiện một API một có một phương pháp mà bạn đi qua một danh sách các đường dẫn mà chương trình đọc nguồn lực từKhi nào muốn sử dụng danh sách varargs vào một mảng?

public void importFrom(String... paths) { 

} 

Tôi đang sử dụng varargs để gọi phương pháp này là thuận tiện càng tốt cho người sử dụng, giống như vậy

obj.importFrom("/foo", "/foo/bar); 

Đây có phải là cách sử dụng thích hợp varargs không? Hoặc là đi qua trong một mảng tốt hơn?

+2

Bạn vẫn có thể chuyển mảng sang phương thức varargs, nó sẽ hoạt động giống nhau. –

Trả lời

7

Trong trường hợp varargs của bạn là tốt. Bạn không thực sự cần tạo một mảng đường dẫn mà bạn sẽ nhập vì không có gì bạn muốn làm với các đường dẫn này ngoài việc chuyển chúng theo phương thức importFrom của bạn.

Chức năng varargs giúp bạn không phải tạo một mảng một cách rõ ràng chỉ nhằm mục đích chuyển một tập hợp các giá trị sang phương thức một lần mà bạn có vẻ ở đây.

BTW, bạn thể vẫn vượt qua trong một mảng nếu bạn muốn

public class VarargsDemo { 
    public static void f(String... args) { 
     for (String s: args) { 
      System.out.println(s); 
     } 
    } 
    public static void main(String[] args) { 
     String[] english = new String[]{"one", "two", "three"}; 
     f(english); 
     f("uno", "dos", "tres"); 
    } 
} 

Bởi vì hành vi này là giống nhau, sự khác biệt đi xuống đến một (có thể là nhỏ) câu hỏi về những gì bạn muốn phương pháp chữ ký để "nói". Khi bạn khai báo một phương thức để lấy tham số mảng rõ ràng, nó gần như là bạn muốn nhấn mạnh rằng bạn muốn hoạt động trên một đối tượng mảng, cái gì đó đã được định nghĩa bên ngoài phương thức và có sự tồn tại và tầm quan trọng riêng của nó bên ngoài phương thức, và một trong số đó, có lẽ, các hoạt động như vấn đề lập chỉ mục. Khi khai báo phương thức với varargs, nó giống như bạn đang nói "chỉ cần cho tôi một loạt các mục".

Sau đó, một lần nữa, điều này không đúng; JVM không biết sự khác biệt, tất cả những gì nó thấy là một mảng tại thời gian chạy. Nhiều lập trình viên sẽ không bận tâm đến việc chia nhỏ lông trên ý định của chữ ký phương thức. Varargs là tất cả về làm cho các cuộc gọi thuận tiện.

Điều đó nói rằng, giới hạn chính của varargs là tham số đó phải là phương thức cuối cùng của phương thức. Trong trường hợp của bạn đây không phải là một vấn đề, nhưng nói chung nó là một cái gì đó để xem xét.

+0

+1 cho mảng đi qua - Tôi vẫn tìm đoạn văn về "phân biệt đối tượng mảng" một chút khó hiểu: Lý do duy nhất tôi thấy để truyền một mảng thực sự là vì vậy người gọi có thể thấy các thay đổi được thực hiện bởi callee (đảo ngược, phân loại) - nhưng tìm kiếm sẽ không yêu cầu điều này? –

+1

Vâng, đó là viết kém và có lẽ không quan trọng khủng khiếp. Tôi viết lại nó một chút để cố gắng làm cho nó ít khó hiểu và cũng cho thấy rằng nó là loại vấn đề nhỏ, nếu nó thực sự là một vấn đề ở tất cả. Cảm ơn. –

2

Câu trả lời tùy thuộc vào mục đích sử dụng chức năng của bạn. Nếu người dùng thường biết thời gian mã hóa mà đối số mà anh ta muốn chuyển vào, thì varargs là cách để thực hiện. Nếu người dùng cần để có thể xác định số lượng các đối số trong thời gian chạy, một đối số mảng sẽ làm cho cuộc sống dễ dàng hơn nhiều đối với anh ta (hoặc cô ta).

+0

Tôi nghĩ anh ta đang nói về một tham số mảng mở. Trong các ngôn ngữ cũ, cách duy nhất để xác định kết thúc của các đối số là sử dụng một chuỗi canary hoặc format. Không phải như vậy trong java. Để đơn giản, tôi sẽ sử dụng varargs vì bạn không cần tạo danh sách tạm thời làm cho mã có khả năng dễ hiểu hơn – Petesh

+0

"Nếu người dùng cần để có thể xác định số lượng đối số khi chạy", anh ta sẽ chuyển một mảng. –

1

Tôi nghĩ cách khác là sử dụng List<String>. Cá nhân tôi sẽ sử dụng một List nếu có nhiều hơn một vài đối số hoặc nếu đối số được tự động xử lý từ đâu đó (được phân tích cú pháp từ một tệp chẳng hạn).

Nếu bạn sẽ viết các đối số theo cách thủ công trong mã, thì tôi muốn sử dụng các vararg như bạn đã đề xuất.

3

Vì đối số varargs được biên dịch thành một đối số mảng, bạn thường có thể thích vararg vì điều này có thể thuận lợi hơn trong một số trường hợp và vẫn cho phép truyền mảng trong các trường hợp khác.

public void importFrom(String... paths) 
{ 
} 

biên dịch vào

public void importFrom(String[] paths) 
{ 
} 

Hoặc bạn cũng có thể sử dụng Iterable<String> để làm cho nó dễ dàng hơn để vượt qua các đối số như bộ sưu tập.

+0

+1 để hiển thị các biên dịch vào. –

Các vấn đề liên quan