2016-08-12 8 views

답변

0

Java의 객체는 실제로 의 다른 객체가 포함되어 있습니다. C 또는 다른 프로그래밍 언어와 다릅니다. 심지어 소위 말하는 "컨테이너"클래스는 실제로 참조를 다른 오브젝트에으로 포함합니다.

변경할 수없는 개체는 다른 개체 (변경 가능 또는 변경 불가능)를 나타낼 수 있습니다.

변경할 수없는 개체가 참조하는 다른 개체는 변경할 수 없지만 변경할 수있는 다른 개체는 변경할 수 있습니다.

1
자바에서

(그리고 지금까지 내가 const/final/readyonly/val 등의 키워드와 다른 모든 주류 언어를 알고있는)에 "불변"개체가 변경 가능한 객체에 대한 참조를 포함 할 수 있습니다. 변경 불능에 대한 자세한 내용은 this paper을 참조하십시오. 즉, 비공식 Java 확장이 있으므로이를 지정할 수 있습니다. 불변 객체는 불변 객체에 대한 참조만을 포함 할 수 있습니다. Javari 또는 Joe3 또는 OIGJ

+0

변경할 수없는 객체의 상태를 수정하는 방식으로 객체 자체가 변경되지 않는 한 변경할 수없는 객체는 변경 가능한 객체 ('char []'는'String'에서 변경할 수 있습니다)로 구성 될 수 있지만 그것으로 구성됩니다. 그러한 상태를 변경하려는 시도는 새로운 객체 (예 : toLowercase() 및 toCharArray())를 생성해야합니다. 그렇지 않으면 객체가 자연스럽게 스레드로부터 안전하지 않게되어 불변의 특성을 크게 위반하게됩니다. 불변 개체가 변경 가능한 개체를 참조하는 경우에는 그 개체에 대한 외부 참조가 없어야합니다. –

+0

문제는 변경 가능한 객체를 참조하는 "불변"객체에 ** ** 가능한지 여부입니다. 그러나 나는 이것이 가능하더라도 이것이 어쩔 수없는 것이라고 전적으로 동의합니다. –

+0

final/readonly를 사용한다고해서 객체 자체가 변경되지 않는 것은 아닙니다. 단지 상수 참조가됩니다. – EJoshuaS

-1

나는 가능하다고 생각합니다. 그러나 가변 객체를 참조하는 변수의 접근 수정자는 반드시 최종적이어야합니다.

+0

"final"은 액세스 한정자가 아닙니다. – EJoshuaS

2

예. 가능합니다. 예를 들어

테이크 java.lang.String의 코드 :

value[0] = '&'; 

그러나 String 여전히 불변이다 : 우리가 쉽게 이런 식으로 자신의 내용을 변경할 수 있기 때문에

/** The value is used for character storage. **/ 
private final char value[]; 

는 물론 배열은 변경할 수 있습니다. 즉, 일단 생성되면 내용이 변경되지 않습니다. 어떻게 된거 야?

value가 변경 가능한 경우에도 수정하는 String의 사용자에 대한 "일반적인"방법이 없기 때문에 :

  1. valueprivate final를 선언가. String 자체는 final이며 서브 클래스가 없음을 의미합니다.
  2. 세터 메소드가 없습니다. value을 수정하는 방법도 없습니다.
  3. char 배열에서 문자열을 만들 수 있지만 char 배열이 생성자 안에 복사되므로 원래 배열을 수정해도 새로 만든 문자열에는 아무런 영향을 미치지 않습니다.
  4. value 필드는 여러 개의 String 인스턴스에서 공유 할 수도 있지만 유출되지 않는 한 안전합니다.
  5. 문자열을 char 배열로 다시 변환 할 수 있지만 다시 복사 할 수 있습니다.

따라서 design strategy을주의 깊게 따르면 대답은 '예'입니다.

0

편집 : 이것은 "불변"이 의미하는 것에 다소 의존합니다. 다른 사람이 지적했듯이, 때때로 "불변"은 "얕은"불변성의 한 형태로 정의됩니다. 즉, 변경 가능한 객체에 대한 지속적인 참조가 허용됩니다. 나는이 정의를 자신이 좋아하지 않는다. 어떤 사람들은 여기에 동의하지 않을 것입니다. (아무도 의견 차이가있는 b/c를 하향 조정하지 않을 것입니다.) "불변성"을 "어떤 종류의 가변적 인 상태가없는"것으로 정의하는 것이 훨씬 더 명확하다고 생각합니다.

이 정의에서 mutable 상태를 제공하는 변경 가능한 객체를 참조하면 객체 자체를 변경할 수 있기 때문에 질문에 대한 대답은 ** no *입니다.

나는 그것이 일정한 참조 또는 포인터 및 불변의 객체 구분하는이 시점에서 중요하다고 생각합니다. 당신은 -

private final string abc = "John"; 

참고가 항상 "존"입니다 특정 문자열 즉 "ABC"(의 상태를 수정할 수 없습니다 예를 들어, 다음 코드는 상수 객체에 대한 일정한 기준입니다 나중에 "Johnny"로 변경할 수 없으면 새 문자열을 만들어야하고 "John"을 새 문자열로 바꿀 수 없습니다 (즉, "abc"변수 자체가 항상 해당 문자열을 참조합니다) .

public string abc = "John"; 
,745 :

다음 코드는 불변 오브젝트에 대한 레퍼런스이다 변경할

(그건 그렇고, 대신 여기에 속성을 사용해야한다는 것을 알고 있습니다.)

당신이 있다면 나중에 할 : 당신이 그렇게하도록 허용 될 것

abc = "Johnny"; 

. 이 경우 변수 "abc"가 참조하는 객체 인 이 아니라 원래의 문자열 인이 변경됩니다. 문자열 "John"은 이 항상이면 해당 값을 갖습니다. (당신이 "카운트"의 값을 변경할 수 있기 때문에)

public class Defg 
{ 
    public int Count; 

    public Defg(int Count) 
    { 
     this.Count = Count; 
    } 
} 

분명히,이 변경 가능한 클래스는 다음과 같습니다

그러나, 다음과 같은 목적을 고려하십시오.

당신은 다음을 수행 할 수 다음과 같은 것을

// Mutable reference to a mutable object. Note: "Count: 1" is a bit of C# syntax that just means that the "Count" parameter is set to 1. It's not strictly necessary here, I just added it for clarity. 
public Defg Mutable = new Defg(Count: 1); 

// Constant reference to a mutable object 
public final Defg ConstReference = new Defg(Count: 1); 

주 모두 완벽 유효 : 그러나

Mutable = new Defg(Count: 10); 
Mutable.Count = 4; 
ConstReference.Count = 3; 

, 당신은 다음을 수행 할 수 없습니다

ConstReference = new Defg(Count: 3); 

을 특히, Defg 상태를 변경할 수 있기 때문에은 불변 개체가 될 수 없습니다.

은 요약하면 :
A)는 상수 객체에 대한 변경 가능한 참조 또는 변경 가능한 객체에 대한 일정한 기준 중 하나를 가지고 완벽하게 가능 -에 참조의 가변성을 개체가 있는지 여부와는 아무 상관이 없습니다 개체 자체는 변경할 수 있으며 은 그 반대의 경우입니다.
b) 변경 가능 객체를 참조하는 객체가 여전히 불변으로 간주 될 수 있는지 여부는 "불변"의 정의에 따라 다릅니다. 내 의견으로는, 변경 가능한 객체를 참조하면 변경할 수있는 상태가되기 때문에 그렇게 할 수 없습니다. 불변으로 기술하는 것이 혼란 스럽거나 오해의 소지가 있습니다.

+0

이 답변은 C#에 대한 지식이 거의없는 사람들에게 다소 혼란 스럽습니다. 나를. –

+0

@LukeLee 충분히 익숙한 구문을 사용하여 편집 할 것입니다. – EJoshuaS