변경 가능한 객체를 포함하는 변경 불가능한 객체를 작성할 수 있습니까? 가능합니까? 이 점에 대해 더 자세히 알려주십시오.Java의 변경 및 변경 불가능한 개념
미리 감사드립니다.
변경 가능한 객체를 포함하는 변경 불가능한 객체를 작성할 수 있습니까? 가능합니까? 이 점에 대해 더 자세히 알려주십시오.Java의 변경 및 변경 불가능한 개념
미리 감사드립니다.
Java의 객체는 실제로 에의 다른 객체가 포함되어 있습니다. C 또는 다른 프로그래밍 언어와 다릅니다. 심지어 소위 말하는 "컨테이너"클래스는 실제로 참조를 다른 오브젝트에으로 포함합니다.
변경할 수없는 개체는 다른 개체 (변경 가능 또는 변경 불가능)를 나타낼 수 있습니다.
변경할 수없는 개체가 참조하는 다른 개체는 변경할 수 없지만 변경할 수있는 다른 개체는 변경할 수 있습니다.
(그리고 지금까지 내가 const
/final
/readyonly
/val
등의 키워드와 다른 모든 주류 언어를 알고있는)에 "불변"개체가 변경 가능한 객체에 대한 참조를 포함 할 수 있습니다. 변경 불능에 대한 자세한 내용은 this paper을 참조하십시오. 즉, 비공식 Java 확장이 있으므로이를 지정할 수 있습니다. 불변 객체는 불변 객체에 대한 참조만을 포함 할 수 있습니다. Javari 또는 Joe3 또는 OIGJ
예. 가능합니다. 예를 들어
테이크 java.lang.String
의 코드 :
value[0] = '&';
그러나
String
여전히 불변이다 : 우리가 쉽게 이런 식으로 자신의 내용을 변경할 수 있기 때문에
/** The value is used for character storage. **/
private final char value[];
는 물론 배열은 변경할 수 있습니다. 즉, 일단 생성되면 내용이 변경되지 않습니다. 어떻게 된거 야?
value
가 변경 가능한 경우에도 수정하는 String
의 사용자에 대한 "일반적인"방법이 없기 때문에 :
value
가 private final
를 선언가. String
자체는 final
이며 서브 클래스가 없음을 의미합니다.value
을 수정하는 방법도 없습니다.value
필드는 여러 개의 String
인스턴스에서 공유 할 수도 있지만 유출되지 않는 한 안전합니다.따라서 design strategy을주의 깊게 따르면 대답은 '예'입니다.
편집 : 이것은 "불변"이 의미하는 것에 다소 의존합니다. 다른 사람이 지적했듯이, 때때로 "불변"은 "얕은"불변성의 한 형태로 정의됩니다. 즉, 변경 가능한 객체에 대한 지속적인 참조가 허용됩니다. 나는이 정의를 자신이 좋아하지 않는다. 어떤 사람들은 여기에 동의하지 않을 것입니다. (아무도 의견 차이가있는 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) 변경 가능 객체를 참조하는 객체가 여전히 불변으로 간주 될 수 있는지 여부는 "불변"의 정의에 따라 다릅니다. 내 의견으로는, 변경 가능한 객체를 참조하면 변경할 수있는 상태가되기 때문에 그렇게 할 수 없습니다. 불변으로 기술하는 것이 혼란 스럽거나 오해의 소지가 있습니다.
이 답변은 C#에 대한 지식이 거의없는 사람들에게 다소 혼란 스럽습니다. 나를. –
@LukeLee 충분히 익숙한 구문을 사용하여 편집 할 것입니다. – EJoshuaS
변경할 수없는 객체의 상태를 수정하는 방식으로 객체 자체가 변경되지 않는 한 변경할 수없는 객체는 변경 가능한 객체 ('char []'는'String'에서 변경할 수 있습니다)로 구성 될 수 있지만 그것으로 구성됩니다. 그러한 상태를 변경하려는 시도는 새로운 객체 (예 : toLowercase() 및 toCharArray())를 생성해야합니다. 그렇지 않으면 객체가 자연스럽게 스레드로부터 안전하지 않게되어 불변의 특성을 크게 위반하게됩니다. 불변 개체가 변경 가능한 개체를 참조하는 경우에는 그 개체에 대한 외부 참조가 없어야합니다. –
문제는 변경 가능한 객체를 참조하는 "불변"객체에 ** ** 가능한지 여부입니다. 그러나 나는 이것이 가능하더라도 이것이 어쩔 수없는 것이라고 전적으로 동의합니다. –
final/readonly를 사용한다고해서 객체 자체가 변경되지 않는 것은 아닙니다. 단지 상수 참조가됩니다. – EJoshuaS