2009-01-28 58 views
11

Tôi có câu hỏi về việc thay đổi các giá trị của các biến trong các phương thức trong Java.Thay đổi giá trị của các biến trong các phương thức, Java

Đây là mã của tôi:

public class Test { 
    public static void funk(int a, int[] b) { 
     b[0] = b[0] * 2; 
     a = b[0] + 5; 
    } 

    public static void main(String[] args) { 
     int bird = 10; 
     int[] tiger = {7}; 

     Test.funk(bird, tiger); 
    } 
} 

Sau khi thực hiện các phương pháp Test.funk(bird, tiger), giá trị của con chim là không thay đổi - nó vẫn còn có giá trị 10, mặc dù trong phương pháp funk() chúng tôi đã thay đổi giá trị với a = b[0] + 5;

Mặt khác, giá trị của các phần tử trong những thay đổi mảng, vì chúng tôi có báo cáo kết quả b[0] = b[0] * 2;

tôi không hiểu tại sao một điều thay đổi và cái kia không? Ai đó có thể vui lòng giải thích điều này cho tôi.

Trả lời

17

Hãy xem bài viết của Jon Skeet về số Parameter-Passing in Java, giải thích điều này.

Tóm lại (xem trang web của anh ấy để được giải thích chi tiết hơn):

Mảng là loại tham chiếu. Nếu bạn chuyển một tham chiếu trỏ tới một mảng, giá trị của tham chiếu sẽ được sao chép và gán cho tham số của hàm. Vì vậy, tham số sẽ trỏ đến cùng một mảng với đối số đã được chuyển. Do đó những thay đổi bạn thực hiện đối với mảng thông qua tham số của hàm sẽ được hiển thị trong hàm gọi. Thay đổi chính tham số (b), ví dụ bằng cách đặt nó thành null, tuy nhiên, sẽ không được chú ý bởi hàm gọi, vì tham số (b) chỉ là một bản sao đối số (tiger) được truyền.

Số nguyên được gọi là các kiểu nguyên thủy. Vượt qua các số nguyên sao chép giá trị của nó và gán nó vào tham số. Nhưng giá trị đó không phải là một tham chiếu đến dữ liệu thực tế, mà chính là dữ liệu. Vì vậy, những thay đổi đối với paramter trong hàm sẽ ảnh hưởng đến tham số (a), nhưng không phải là đối số được truyền trong hàm gọi (chim).

4

Đó là bởi vì khi bạn khai báo

public static void funk(int a, int[] b) 

Phạm vi của biến một là phương pháp duy nhất đó. Sau đó, khi bạn thay đổi giá trị, bạn chỉ thay đổi giá trị của rằng biến số trong phương thức đó.

Giới thiệu về b. Thats một tham chiếu đối tượng mới để cùng một mảng được tạo ra trong chính, đó là lý do tại sao nó dường như giá trị không thay đổi (những gì đang thay đổi là đối tượng mảng bên dưới)

Nhưng thử điều này:

public static void funk(int a, int[] b) { 
    // create a new reference for b 
    int[] c = new int[b.length]; 
    c[0] = b[0]; 
    b = c; 

    // The same. 
    b[0] = b[0] * 2; 
    a = b[0] + 5; 
} 

Khi bạn làm điều đó bạn sẽ giá trị của hổ không thay đổi (hoặc chỉ nội dung của mảng mới c được tạo ra trong funk)

Bạn có thể mô phỏng thông qua ref bằng cách sử dụng trình bao bọc.See this post.

Mặc dù tôi đã không có bất kỳ ý kiến ​​về điều đó

EDIT Just for fun:

tôi đã sửa đổi mã của bạn để sử dụng các wrapper đăng ở trên.

Có vẻ khá lạ nhưng có vẻ như nó hoạt động.

// By ref simulated. 
public class Test { 

    public static void funk(_<Integer> a, int[] b) { 
     b[0] = b[0] * 2; 
     a.s( b[0] + 5) ; 
    } 

    public static void main(String[] args) { 
     _<Integer> bird = new _<Integer>(10); 
     int[] tiger = {7}; 

     Test.funk(bird , tiger); 

     System.out.println("bird = " + bird); 
     System.out.println("tiger = " + tiger[0]); 

    } 

} 

Prints

bird = 19 
tiger = 14 

: -S

4

Về cơ bản, các đối tượng (như mảng) được truyền vào phương pháp "bằng cách tham khảo". Vì vậy, khi bạn thay đổi đối tượng, nó thay đổi cùng một đối tượng được truyền vào phương thức.

Primitives (như int) đều được "truyền theo giá trị", do đó biến bạn đang gán một giá trị để trong một không giống như các biến int mà đã được thông qua.

Tôi hy vọng điều này sẽ giúp .. .

+1

không, nó không giúp đỡ. Java là ALWAYS pass-by-value. Đọc các liên kết được cung cấp trong các câu trả lời khác; bạn cần hiểu điều này. –

+0

Ví dụ này giải thích 'cơ bản' của tôi là tốt. Tôi đã nói rõ rằng đó là một lời giải thích cơ bản. Nếu người hỏi muốn đọc một lời giải thích sâu hơn thì các liên kết có đó cho anh ta. Tôi không có cách nào để nói anh ta yêu cầu bao nhiêu chi tiết, vì vậy anh ấy nghĩ rằng anh ấy có thể đánh giá cao sự lựa chọn. – stephendl

+1

Vâng, tôi đã đánh giá cao nó. Tôi cũng đọc các liên kết, nhưng giải thích ngắn hơn cũng hữu ích để giúp bạn bắt đầu. Cảm ơn tất cả. – user42155

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