2009-09-01 2 views
-1
class MetaData { 
    public String version; 
    public String compression; 
} 

메타 데이터 객체를 만들고 메서드에 전달한 다음 메서드 내에서 버전 및 압축 필드를 채 웁니다. 그리고 이러한 변화가이 방법의 수명이 다할 때까지 존재하기를 바랍니다. C++에서 나는 & 또는 오브젝트 자체를 전달하기위한 메소드를 추가하고 메소드의 사본을 전달하지는 않는다고 생각합니다. Java로도 똑같이 할 수 있습니까?Java에서 메소드 자체에 객체 자체를 전달할 방법이 없으므로 실제로 변경됩니까?

+3

이 질문은 거꾸로 보입니다. 이 객체를 함수에 전달하고 함수가 버전 및 압축을 변경하면 새 값이 호출자에게 표시됩니다. 변경 사항을 보이지 않게 만드는 것은 MetaData 참조를 새 값으로 변경 한 경우입니다. – Jay

+0

글쎄, 불행히도, 그건 사실이 아니야. 감사. – sepiroth

답변

17

이것은 항상 Java에서 발생합니다. 자바가 작동하는 방식 일뿐입니다. 메서드에 "MetaData"객체를 전달하면 해당 객체에 대한 참조가 전달되고 "버전"및 "압축"필드에 대한 모든 수정 사항을 모든 곳에서 볼 수 있습니다.

체크 아웃 정말 깊이있는 설명은이 문서 :

http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html

5

Java has pass by value semantics. 이것은 객체가 값에 의해 메소드에 전달된다는 의미는 아닙니다. 대신 객체에 대한 참조가 값에 의해 메소드에 전달된다는 의미입니다.

따라서이 시나리오에서는 MetaData 개체를 만들고 필드에 채워지는 메서드에 전달할 때 개체에 대한 참조가 해당 메서드에 전달됩니다. 메서드가 반환되면 호출자의 개체 참조를 검사하여 해당 필드가 설정되어 있는지 확인할 수 있습니다.

그런데, 이것은 객체의 상태를 설정하기 위해 다른 클래스에 MetaData 객체를 보내는 경우 OOP에서 나쁜 습관입니다. 객체 자체가 자신의 상태를 담당해야합니다.

4

Java의 기본 동작입니다.

class Example { 
    public static void doit(MetaData data) { 
    data.compression = "Testing" 
    } 

    public static void main(String[] args) { 
    MetaData data = new MetaData(); 
    doit(data); 
    System.out.println(data.compression); 
    } 
} 
1

메서드에 전달하는 모든 변경 가능한 개체를 변경하면 원본이 변경됩니다. 문제는 String을 변경할 수 없다는 것입니다.

변경할 수있는 개체를 전달하십시오.

"버전"을 변경하려면 클래스 "MetaData"에 .setVersion() 메소드를 지정하고 메소드에 "MetaData"를 전달하십시오. 당신의 메소드는 metaData.setVersion ("나는 새로운 것")을 호출 할 것이다; 모두가 행복해 할 것입니다. 당신이 할 수없는 것은 문자열과 기대 방법에 패스 "버전"

public void willWorkFine (Metadata metaData) { 
    metaData.setVersion("Changed!"); 
} 

인을 재 할당합니다 :

public void wontWork(String changeMe) { 
    changeMe="not changed!"; 
} 

을 changeme를 원래 "버전"단지 로컬 참조이기 때문에 다른 개체를 가리 키도록 로컬 참조를 다시 할당해도 외부 프로그램에는 아무런 영향을 미치지 않습니다.

관련 문제