2012-07-20 19 views
5

Tôi biết rằng trong Java, mọi thứ đều được truyền theo giá trị. Nhưng đối với các đối tượng, nó là giá trị của tham chiếu đến đối tượng được truyền. Điều này có nghĩa rằng đôi khi một đối tượng có thể thay đổi thông qua một tham số, đó là lý do tại sao, tôi đoán, mọi người nói, Không bao giờ sửa đổi các tham số.Băng qua "Giá trị tham chiếu"? Một số làm rõ cần thiết

Nhưng trong đoạn mã sau, có điều gì đó khác xảy ra. s trong changeIt() không thay đổi khi bạn nhận được trở lại main():

public class TestClass { 

    static String str = "Hello World"; 

    public static void changeIt(String s) { 
     s = "Good bye world"; 
    } 

    public static void main(String[] args) { 
     changeIt(str); 
     System.out.println(str); 
    } 
} 

Tôi đoán - và tôi muốn xác nhận - đó là khi bạn nói s = "something" nó giống hoặc tương đương với nói String s = new String("something"). Đây có phải là lý do vì sao s không thay đổi? Có phải nó đã được gán một đối tượng hoàn toàn mới cục bộ bị bỏ đi khi bạn thoát khỏi changeIt()?

+1

Tôi đã thấy loại câu hỏi/câu trả lời này trước đây và tôi vẫn * cảm thấy mình cần đánh giá. +1 – BlackVegetable

+0

Nó không thay đổi vì các chuỗi trong Java là các đối tượng bất biến. – anio

+1

@anio Không, đó không phải là lý do mã cụ thể này không thay đổi chuỗi. Nó sẽ là hành vi tương tự cho bất kỳ đối tượng, bất biến hay không (kể từ khi ông đang làm nhiệm vụ, không gọi bất kỳ phương pháp trên đối tượng nhận được) – nos

Trả lời

4

rằng khi bạn nói s = "cái gì đó" nó giống hoặc tương đương với nói String s = new String ("cái gì đó")

Có, khá nhiều. (mặc dù JVM có thể làm tối ưu hóa để cùng một chuỗi ký tự được sử dụng nhiều lần đề cập đến cùng một đối tượng String).

Đây có phải là lý do tại sao s không thay đổi? Có phải nó được gán một đối tượng hoàn toàn mới cục bộ được bỏ đi khi bạn thoát khỏi changeIt()

Có. Như bạn nói, mọi thứ được truyền theo giá trị trong Java, thậm chí là các tham chiếu tới đối tượng. Vì vậy, biến s trong changeIt(String s) là một giá trị khác nhau từ str bạn sử dụng trong main(), nó chỉ là một biến cục bộ trong phương thức changeIt. Đặt tham chiếu đó để tham chiếu một đối tượng khác không ảnh hưởng đến người gọi changeIt.

Lưu ý rằng các đối tượng String s tham khảo vẫn là như nhau String như str đề cập đến khi vào phương pháp changeIt() trước khi bạn gán một đối tượng khác nhau để s

Có một điều bạn cần phải nhận thức được, và rằng là các chuỗi không thay đổi. Điều đó có nghĩa là không có phương thức nào bạn gọi trên một đối tượng chuỗi sẽ thay đổi chuỗi đó. ví dụ. gọi s.toLowerCase() trong phương thức changeIt() của bạn cũng sẽ không ảnh hưởng đến người gọi. Đó là bởi vì String.toLowerCase() không thay đổi đối tượng, mà là trả về một đối tượng String mới.

0

Có, bây giờ 'S' trỏ tới đối tượng hoàn toàn mới có phạm vi giới hạn trong phương pháp đó. Chuỗi có thể không phải là ví dụ hoàn hảo để hiểu khái niệm truyền theo giá trị. Thay vì chuỗi, chúng ta hãy nói vượt qua một số tham chiếu đối tượng có thể thay đổi và thực hiện thay đổi để gán đối tượng mới bên trong phương thức. Bạn không thấy chúng bên ngoài đối tượng.

public class MyMain { 

    private static void testMyMethod(MyMain mtest) { 
     mtest=new MyMain(); 
     mtest.x=50; 
     System.out.println("Intest method"+mtest.x); 
    } 
    int x=10; 
    public static void main(String... args) 
    { 
     MyMain mtest = new MyMain(); 
     testMyMethod(mtest); 
     System.out.println("In main method: "+mtest.x); 
    } 
} 

Đọc câu trả lời thứ hai trong số SO discussion.

+0

Điều này là sai, bạn sẽ thấy các thay đổi được thực hiện đối với các đối tượng có thể thay đổi: 'static Point myPoint = new Point (0,0); thay đổi khoảng trống công cộngNó (Điểm p) { p.setLocation (1,0); } \t chính trống tĩnh công cộng (Chuỗi [] args) { changeIt (myPoint); System.out.println (myPoint); \t} 'Sẽ in ra' java.awt.Point [x = 1, y = 0] ' – NominSim

+0

@NominSim: Vui lòng kiểm tra ví dụ của tôi và khi bạn thực hiện tham số là cuối cùng, thì không thể gán đối tượng mới cho tham chiếu đó. – kosa

+0

@NominSim: Và nếu câu trả lời thứ hai có thể có trong liên kết này. http://stackoverflow.com/questions/40480/is-java-pass-by-reference – kosa

3

Khi bạn viết

s = "Good bye world"; 

bạn đang thay đổi giá trị của s là một tham chiếu đến chuỗi mới. Bạn không thay đổi giá trị của chuỗi được tham chiếu bởi s.

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