2009-06-19 28 views
9

Tôi đã cố gắng chuyển danh sách khởi tạo {...} cho một hàm tạo và nó không hoạt động. Khi tôi thay vào đó tuyên bố nó trong một biến địa phương phương pháp (int []) nó làm việc hoàn hảo.Tại sao chuyển {a, b, c} sang phương thức không hoạt động?

Tại sao lại như vậy?

public class QuickSort { 
    int[] a; 

    public QuickSort(int[] a) { 
     this.a = a; 
    } 

    public static void main(String[] args) { 
     // ################### 
     // ### WORKS  ## 
     // ################### 
     int[] a = {8,12,79,12,50,44,8,0,7,289,1}; 
     QuickSort sort = new QuickSort(a); 

     // ################### 
     // ### DOESN'T WORK ## 
     // ################### 
     //QuickSort sort = new QuickSort({8,12,79,12,50,44,8,0,7,289,1}); 
    } 
} 
+0

Khi nó xảy ra, những gì đã trở thành các tính năng ngôn ngữ varargs (như java.util.Arrays.asList) ban đầu sẽ làm điều đó. Nó có lẽ là một sai lầm để thay đổi nó ... –

Trả lời

20

Khi khai báo int[] và gán {1, 2, 3} trình biên dịch biết bạn muốn tạo một int[] vì nó được viết ngay tại đó.

Trong trường hợp sau, nơi bạn dính vào mảng trực tiếp vào phương pháp gọi bạn sẽ phải sử dụng

QuickSort sort = new QuickSort(new int[] {8,12,79,12,50,44,8,0,7,289,1}); 

nói với trình biên dịch gì mảng của bạn.

+0

Tôi hiểu. Cảm ơn bạn. –

-1

Bạn đã thử truyền danh sách vào int [] trước khi chuyển nó tới hàm tạo không?

+0

Có, (int []) {1,2,3} đã không hoạt động. –

4

Điều này có thể do danh sách khởi tạo của bạn không có thông tin nhập vào nó. Hãy thử cách này:

QuickSort sort = new QuickSort(new int[] {8,12,79,12,50,44,8,0,7,289,1}); 
2

Java không thực sự có suy luận kiểu. Các khai báo biến mảng là một special case trong đặc tả ngôn ngữ Java, một trong đó không áp dụng cho các tham số phương thức. Làm như vậy sẽ là có thể, nhưng sẽ thêm rất nhiều phức tạp cho spec, vì nó sẽ phải xử lý các câu hỏi như liệu {"a", "b"} tạo ra một String [] hay một Object [] - trông hiển nhiên ở đây, nhưng nếu đó là các đối tượng trong một hệ thống phân cấp kiểu phức tạp thì sao? Và nếu phương pháp này bị quá tải và cả hai phiên bản tồn tại thì sao?

4

Bạn cũng có thể làm như thế này:

public class QuickSort { 
    int[] a; 

    public QuickSort(int ... a) { 
     this.a = a; 
    } 

    public static void main(String[] args) { 

     QuickSort sort = new QuickSort(8,12,79,12,50,44,8,0,7,289,1); 
    } 
} 
+0

Rất đẹp! Tôi sẽ sử dụng tính năng này. –

10

Các cấu trúc {} được gọi là khởi tạo mảng, và nó được sử dụng để khởi tạo một mảng trong Java. (Tham khảo: Section 10.6: Array Initializers từ The Java Language Specification, Third Edition.)

Lý do tại sao tự mình vượt qua {1, 2, 3} là không hợp lệ vì không có thông tin loại liên quan đến bộ khởi tạo.

Vì vậy, người ta phải cho trình biên dịch biết loại mảng là bằng cách viết new Type[], trong đó Type là loại mà mảng được tạo cho.

Sau đây là tất cả sử dụng hợp lệ initializer mảng:

  • new String[] {"Hello, "World"}
  • new Character[] {'A', 'B'}
  • new Runnable[] {new Runnable() {public void run() {}}, new Runnable() {public void run() {}}

Như có thể thấy, ký hiệu này có thể được sử dụng cho nhiều loại dữ liệu , vì vậy nó không phải cái gì đó là cụ thể cho số nguyên.

Đối với:

int[] a = {1, 2, 3}; 

Lý do tại sao ở trên là hợp lệ là bởi vì loại thông tin được cung cấp cho các trình biên dịch trong khai báo kiểu dữ liệu, mà trong trường hợp này là int[]. Có gì ở trên là ngụ ý như sau:

int[] a = new int[] {1, 2, 3}; 

Bây giờ, nếu chúng ta có new int[] {1, 2, 3}, chúng tôi có thể tạo ra một int[] mảng mới tại chỗ, do đó có thể được xử lý như bất kỳ int[] mảng khác sẽ - nó chỉ là rằng nó không có tên biến được liên kết với nó.

Do đó, mảng tạo ra bởi new int[] {1, 2, 3} có thể được gửi vào một phương pháp hoặc constructor mà phải mất một int[] như là đối số của nó:

new Quicksort(new int[] {1, 2, 3}); // This will work. 
0

niềng răng Quăn (khi sử dụng trong literals mảng) chỉ có thể được sử dụng khi khai báo array :)

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