2012-01-23 3 views
2

나는 이것을 둘러 보지 못했고 관찰자 패턴을 구현하는 객체와 피할 수있는 목록의 객체에서 변경 이벤트가 트리거 될 때마다 리스너를 목록에 추가 할 수있는 List 구현이 있습니다. 목록에있는 각 객체에 리스너를 수동으로 추가/제거합니다.개체를 Java 컬렉션에 추가 할 때 값 또는 참조가 추가됩니까?

동일한 목록 구현의 새 인스턴스를 만들고 기존 목록의 개체를 추가 할 때 개체 변경 내용이 새 목록에 추가 된 콩에서 트리거되지 않는 문제가 있습니다. 내 생각에 컬렉션에 객체를 추가 할 때 기존 객체에 포인터를 추가하면 변경 알림이 새 목록의 객체에서 트리거되지만이 경우에는 발생하지 않습니다. 아무도 내가 문제를 파악할 수 있습니까? 비슷한 질문을 보았지만이 문제를 해결하는 데 도움이되는 것은 없습니다.

유스 케이스는 하나의 목록에 내가 본 시장의 모든 주식을 보유하고 있으며 스캐너 목록에는 기준을 통과하는 주식 만 있지만 스캐너는 가격, 수량 등과 같은 업데이트를받지 못합니다 관측 패턴을 사용하여 트리거됩니다. - Duncan

+1

가능한 복제본 [값으로 전달 하시겠습니까? Java에서 참조로 전달 하시겠습니까?] (http://stackoverflow.com/questions/7301637/pass-byvalue-or-pass-by-reference-in-java) –

답변

-5

Java 객체는 항상 참조로 전달됩니다.

그래서 컬렉션의 "add"메소드가 (객체를 복제하거나 프로토 타입으로 사용하는 등) 다른 작업을 수행하지 않는 한 모든 것이 작동해야합니다.

귀하의 문제는 컬렉션 자체 내에서보다 알림의 논리에 더 가깝다고 생각합니다. 몇 가지 코드를 붙여 넣는 것이 좋습니다.

+5

OscarRyz의 답변보기 값으로 전달되지만 값은 참조 값입니다. – 5StringRyan

+0

알림 논리에 대한 좋은 지적은 내 문제의 일부라고 생각합니다. –

-3

예, 모든 클래스 (단순 유형이 아닌)는 참조로 전달되었습니다.

개체를 지원하는 경우 문제를 해결하려면 복제본을 사용할 수 있습니다.

+0

오스카 리즈 (OscarRyz)의 대답을 참조하십시오. – 5StringRyan

9

귀하의 이해가 정확합니다. 컬렉션은 객체에 대한 참조를 보유합니다. 예를 들어,이 :

final StringBuilder stringBuilder = new StringBuilder(); 
final List<StringBuilder> stringBuilderList = new ArrayList<StringBuilder>(); 
stringBuilderList.add(stringBuilder); 
stringBuilderList.add(stringBuilder); 
stringBuilder.append("yes"); 
System.out.println(stringBuilderList); 

이 인쇄됩니다 :

[yes, yes] 

단 하나의 StringBuilder 인스턴스가 있었기 때문에, 첨부 된 "yes" 목록의 모든 요소에 그래서.

그러나이 컬렉션에는 이라는 값이이 아닌 이 아니라이라는 참조가 들어 있습니다. 예를 들어, 다음 :

StringBuilder stringBuilder = new StringBuilder("yes"); 
final List<StringBuilder> stringBuilderList = new ArrayList<StringBuilder>(); 
stringBuilderList.add(stringBuilder); 
stringBuilder = new StringBuilder("no"); 
// now stringBuilder refers to a different object than before 
stringBuilderList.add(stringBuilder); 
System.out.println(stringBuilderList); 

이 인쇄 것이다

[yes, no] 

을리스트의 두 요소가 서로 다른 객체를 참조하기 때문에, 두 물체가 동일한 변수로 확인되었다하더라도.

코드에 어떤 문제가 있는지 파악하는 데 도움이 필요하면 문제를 나타내는 최소한의 프로그램을 게시해야합니다.

5

값으로, 항상!

개체의 경우 전달 된 값은 참조 값이지만 자체 참조는 아닙니다.참조로 전달할 지원 그래서

Foo foo = new Foo();//create a new object 
foo.name("Old foo"); // label it 
modify(foo); // try to modify it 
// In a language that supports byRef will print "New foo". 
// In Java will print "Old foo" always 
println(foo); 
... 
void modify(Foo foo) { 
    foo = new Foo(); // reference assigned a new different object 
    foo.name("New foo"); 
} 

, 언어 새 개체를 넣어 것입니다 : 참조로 패스가 지원

See most of these links

언어 (자바가이 기능을 지원하지 않습니다) 다음을 수행 할 수 있습니다 (그들은 레퍼런스을 받는다.). ++과 VB C와 같은 언어는이 작업을 수행 할 수 있습니다 .. (자바와 같은) 참조로 패스를 지원하지 않습니다

언어를 원래의 참조에 새 개체를 할당하지 않습니다, 자바는의 사본에 할당됩니다 참조 (인수 전달에서 생성 된 것 ->void modify(Foo foo) {) 그러나 원래의 메소드는 메소드 이전에 생성 된 것으로 원래 그대로 남아 있으므로 여전히 Old foo입니다.

+1

IMHO "참조로 전달됨"이라고 말하는 것이 더 유익합니다. 물론, 참조는 값이지만, 나는 그 논거가 의미론을 가지고 놀고 있음을 알게된다. 당신은 "객체와 같은 것은 존재하지 않으며 참조의 값만 있습니다"라고 말할 수 있습니다. – Bohemian

+0

@ 보헤미안 물체는 외부에서 접근 할 수없는 출구가 있습니다. C++이나 VB와 같은 다른 프로그래밍 언어를 사용하면 참조를 직접 수정할 수 있습니다. – OscarRyz

+1

@ 보헤미안, "가치에 의한 전달"에 대해 약간 확장하는 것이 유익 할 것이라고 나는 동의하지만 "참조로 전달"하는 것은 적절하지 않습니다. 이것은 Java가'void swap (String a, String b)'를 지원한다는 것을 암시합니다.'void x, "y"Y "; 스왑 (x, y);'(Java에서는 불가능합니다!). –

1

Java 사양에 따라 모든 것이 Java에서 값으로 전달됩니다. 이 SO discussion에는 작동 원리에 대한 예제가 매우 잘 설명되어 있습니다. 특히 두 번째 대답을 읽습니다.

관련 문제