2015-09-11 18 views
5

Hỗ trợ Java truyền theo giá trị (luôn hoạt động trên bản sao) nhưng khi bạn chuyển đối tượng do người dùng xác định thì nó sẽ thay đổi đối tượng thực tế (loại truyền theo tham chiếu nhưng không thay đổi con trỏ) hiểu nhưng tại sao phương thức changeObject2CLEAR dưới đây thực sự thay đổi giá trị của đối tượng? Thay vào đó nó phải làm việc trên bản sao?Vấn đề với việc truyền theo giá trị trong java


import java.util.HashMap; 
import java.util.Map; 

public class PassBy { 

    class CustomBean { 
     public CustomBean() { 

     } 

     private int id; 
     private String name; 

     public int getId() { 
      return id; 
     } 
     public void setId(int id) { 
      this.id = id; 
     } 
     public String getName() { 
      return name; 
     } 
     public void setName(String name) { 
      this.name = name; 
     } 

     @Override 
     public String toString() { 
      return id + ", " + name; 
     } 
    } 

    public Map<Integer, String> changeObject2NULL (Map<Integer, String> m) { 
     m = null; 
     return m; 
    } 

    public Map<Integer, String> changeObject2CLEAR (Map<Integer, String> m) { 
     m.clear(); 
     return m; 
    } 

    public CustomBean changeCustomObject (CustomBean _e) { 

     _e.setId(_e.getId() + 1); 
     return _e; 
    } 

    public static void main(String[] args) { 

    PassBy passby = new PassBy(); 

    Map<Integer, String> map = new HashMap<Integer, String>(); 
    map.put(1, "value"); 

    CustomBean bean = passby.new CustomBean(); 
    bean.setId(1); 
    bean.setName("arun"); 

    // Initial Value 
    System.out.println(map.toString()); 
    System.out.println(bean.toString()); 
    System.out.println("-------------------------"); 

    // Pass by value works fine 
    passby.changeObject2NULL(map); 
    passby.changeCustomObject(bean); 

    // Custom object value changes since we pass as the object reference but Map remains with actual value 
    System.out.println(map.toString()); 
    System.out.println(bean.toString()); 
    System.out.println("-------------------------"); 

    // Testing Pass by value - CANT UNDERSTAND why it changed the object since it has to be pass-by-value and not by ref in this case ?? 
    // Why setting to null not chainging the value but clear does ? 
    passby.changeObject2CLEAR(map); 
    System.out.println(map.toString()); 

    } 
} 
+0

Bạn đang chuyển * tham chiếu * theo giá trị. Rất nhiều về điều này trên Google. Câu hỏi hay. – Bathsheba

+1

@Arun Tôi đã cập nhật câu trả lời của tôi để giải quyết các hình thức tinh tế của câu hỏi của bạn –

+0

Trong ngắn 'changeObject2NULL (Bản đồ m)' chứa biến * cục bộ * riêng của nó 'm' cũng là tham số phương thức. Khi bạn sử dụng phương thức này như 'changeObject2NULL (map)' 'm' sao chép thông tin về đối tượng' map' giữ (địa chỉ này là * value * của biến 'map'). Vì vậy, khi bạn gọi 'm.clear()', nó gọi phương thức 'clear' trên cùng một đối tượng' map' giữ để bạn có thể thấy trạng thái mới của đối tượng đó thông qua 'map'.Khi bạn gọi 'm = null', bạn chỉ cần thay đổi đối tượng' m' nào thành 'null'; điều này không ảnh hưởng đến 'bản đồ' hoặc đối tượng mà nó đang đề cập đến. – Pshemo

Trả lời

1

Khi bạn gọi changeObject2CLEAR

passby.changeObject2CLEAR(map); 

bạn đang đi qua các ví dụ map.

trong phương pháp changeObject2CLEAR

public Map<Integer, String> changeObject2CLEAR (Map<Integer, String> m) { 
    m.clear(); 
    return m; 
} 

bạn thực hiện .clear() trên cùng dụ map mặc dù trong phương pháp này nó được gọi là m.

Như một bài tập trong việc hiểu thông báo rằng phương pháp sau đây cũng sẽ thực hiện tương tự.

public void changeObject2CLEAR (Map<Integer, String> m) { 
    m.clear(); 
} 

Chú ý rằng bạn không cần phải trả lại Map<Integer, String> mmap bạn có quyền truy cập vào là đối tượng cùng một ví dụ thông qua vào bất cứ nơi nào phương pháp này được gọi.

CHỈNH SỬA: Tại sao m = null; hoạt động như giá trị trả theo giá trị nhưng m.clear() hoạt động như vượt qua tham chiếu?

Khi bạn gán 'giá trị null để m bạn đang thay đổi các tài liệu tham khảo từ các đối tượng dụ trước map đến một vị trí bộ nhớ mới đó là null.

Khi bạn gọi phương thức .clear() trên đối tượng dụ m bạn đang gọi phương pháp trên cùng một đối tượng đó là tại vị trí bộ nhớ được tham chiếu bởi map, do đó bạn chỉnh sửa các đối tượng map.

0

AFAIK Java chỉ thực hiện vượt qua bằng giá trị, nhưng giá trị thực sự tham chiếu

+0

Điều này đúng với các trường hợp 'Đối tượng' nhưng không phải cho các kiểu nguyên thủy –

+0

Tại sao thiết lập đối tượng thành null là giá trị truyền qua nhưng phương thức rõ ràng là pass-by-ref? – AKS

+0

'null' là tham chiếu, do đó, bằng cách gán null, bạn đang thay đổi tham chiếu trong phạm vi hiện tại, do đó" mất "đối tượng bạn đang làm việc, trong khi rõ ràng làm thay đổi đối tượng có tham chiếu mà bạn đã chuyển vào hàm downView, – miau

3

Vì vậy, hãy để tôi cố gắng giúp bạn hiểu, Java luôn không đi qua giá trị, nhưng tôi chắc chắn bạn biết rằng tất cả các cá thể đối tượng đều thực sự trỏ đến các đối tượng đó. Bây giờ khi bạn gửi một đối tượng thì bạn đang chuyển một giá trị của địa chỉ của đối tượng. Nếu bạn thực hiện bất kỳ thay đổi nào đối với chính đối tượng đó (như m.clear()) thì nó sẽ đi đến địa chỉ đó, gõ vào đối tượng và thực hiện thao tác trên nó. Nhưng nếu bạn thay đổi con trỏ chính nó, như m = null, thì chỉ có bản sao của địa chỉ bạn đang nắm giữ được thay đổi.

+2

, quan tâm để bình luận? Đây là câu trả lời đúng. Ít nhất, không phải là một câu trả lời sai. –

+0

Vì câu hỏi là trùng lặp, tôi sẽ bỏ phiếu cho tất cả các câu trả lời trong cả câu hỏi này và bản sao. Các câu trả lời trong bản sao là rất cao cấp hơn này. Vì vậy, IMO, nó không thêm bất cứ điều gì hữu ích. Nếu bạn có gì đó để thêm, sau đó thêm câu trả lời cho bản sao. – Bathsheba

+1

@Bathsheba Trong khi bạn tất nhiên miễn phí để downvote như bạn vui lòng, tôi thấy rằng một nguyên tắc tốt là để downvote khi một câu hỏi là tích cực sai hoặc có hại. Nếu nó không tốt như câu trả lời khác, thì tôi sẽ upvote câu trả lời tốt hơn và chỉ để lại câu trả lời ít tốt hơn bị ảnh hưởng. Nói cách khác, tôi giúp các câu trả lời tốt hơn vươn lên hàng đầu, và đừng lo lắng về việc cố gắng làm cho các câu trả lời kém tốt hơn bị chìm. – yshavit

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