2013-10-17 2 views
0

불변이란 인스턴스화 후에 상태를 변경하지 않는 개체라는 것을 이해합니다. 그러나이 코드 줄에서는 배열 값이 선언 될 때 Final이 표시되지 않습니다. 이 클래스는 불변입니까? 누구든지 찾아내는 방법을 설명 할 수 있습니까? 감사합니다불변 클래스 tell to tell

public class A { 
private double[] values; 
public double[] getValues(){ 
return values; 
} 
} 
+0

java에서 String 클래스의 구현을 참조하십시오. 변경 불가능한 클래스의 가장 좋은 예입니다. http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/String.java –

+2

'final'은 실제로 여기서 도움이되지 않습니다. 복사본이 없으면 불변의 배열을 반환합니다. –

답변

0

예 붙여 넣은 코드가 어떤 최종 키워드가 관련된 어떠한 불변의 행동이 없습니다 가지고 있지 않습니다.

그럼 난 자바 불변의 클래스를 작성과 관련된 몇 가지 주요 지침을 맺게 싶습니다 :

1) 클래스를 확인 오버라이드 (override) 할 수 없습니다 -

개인 생성자를 클래스가 최종 확인 또는 정적 공장을 사용하고 유지

2. 필드를 비공개로 만들고 마지막으로 호출자는 인수가없는 생성자를 setXXX 메서드에 대한 호출과 결합하여 (즉, Java Beans 규칙을 사용하지 않고) 단일 단계로 완전히 생성하도록합니다.

3.) 나를 제공하지 마십시오. 어떤 방식 으로든 객체의 상태를 변경할 수있는 thods - setXXX 메소드뿐만 아니라 상태를 변경할 수있는 메소드

4. 클래스에 변경 가능한 객체 필드가있는 경우 전달할 때 방어 적으로 복사해야합니다 클래스와 호출자 사이

+0

속성 (또는 메소드)이 모든 패키지의 클래스 서브 클래스에서 액세스 할 수 있지만 은 다른 패키지의 다른 클래스에서 액세스 할 수 없도록 public 클래스의 속성에 어떤 수정자를 사용해야합니까? 이 기본값이 될까요? – Juan

+0

@Juan 보호. 기본 수정자는 동일한 패키지의 모든 클래스가 액세스 할 수 있도록합니다. protected는 서브 클래스입니다. 귀하의 게시물에 두 번째 읽기를 제공 한 후에 두 가지 사이의 하이브리드가 필요합니다. – Cruncher

+1

@Cruncher -'protected'는 모든 패키지의 서브 클래스와 _ 동일한 패키지의 모든 코드에 의한 액세스를 허용합니다. –

0
A a = new A(); 
a.getValues()[0] = 1.2; 

값이 비어 있지 않은 한 계속 작동합니다. 그러나 새 배열에 값을 재 할당 할 수는 없습니다. 즉 : a.getValues() = new double[5];가 작동하지 않습니다.

클래스를 변경할 수 없으므로 값을 변경할 수 있으므로 다시 할당하지 마십시오.

0

다음은 간단한 확인입니다. 값은 1,2로 초기화됩니다. 개체

public class A { 
    private double[] values; 

    public double[] getValues() { 
     return values; 
    } 

    public static void main(String[] args) { 
     A test = new A(); 
     test.values= new double[]{1, 2}; 

     double[] valuesref = test.getValues(); 
     valuesref[0] = 10; 

     for (int i = 0; i < test.values.length; i++) { 

      System.out.println(test.values[i]);  
     } 
    } 
} 

에 getValues ​​()는 사본을 반환하면이 피할 수를 생성 한 후 흡착제와 기준을 사용

하나의 배열에서 첫 번째 항목의 내부 값을 변경할 수있다 정렬.

+0

이것은'test.values ​​='가 다른 클래스에서 작동하지 않기 때문에 일종의 부정 행위이다. 그러나 이것은 어쨌든 요점을 나타낼 것이라고 생각합니다. – Cruncher

+0

맞아요, setter 나 기본이 아닌 생성자가없는 클래스의 사용은 매우 제한적입니다. 배열이 참조를 사용하여 값을 변경할 수 있다는 사실을 강조하고 싶었습니다. – Ram

1

다른 사람이 쓰는 것처럼이 개체는 상태가 변경 될 수있는 것으로 간주됩니다. 변경할 수없는 것은 보유하고있는 배열을 교환 할 수 없다는 것입니다. 하지만 배열의 내용을 변경할 수 있습니다 (getValues ​​() [0] = 10;).

이 개체를 불변 개체로 변환하려면 배열 대신 목록을 사용해야합니다. 목록으로 Collections '방법 unmodifiableList을 사용하여 특정 목록을 외부로 공개 할 수있는 버전으로 변환 할 수 있습니다. getValues ​​()의 호출 측이 변경 불가능한리스트로 add 또는 remove를 사용하면, UnsupportedOperionException가 발생 해, 오브젝트의 변경이 보존되지 않게됩니다.

배열을 고수해야하는 경우 배열의 복사본 (System.arraycopy) 또는 복제본 (clone())을 제공해야합니다.

일반적으로 개체는 속성 (예 : 수퍼 클래스에서 상속 된 속성 포함)을 변경할 수없는 경우 변경할 수없는 것으로 간주됩니다. 일반적으로 속성 값도 포함되지만 흐리게 정의됩니다.

예를 들어 문서 파일을 가리키는 File 인스턴스를 보유하는 클래스가 있고이 File 인스턴스를 변경할 수없는 경우 클래스는 변경 불가능한 것으로 간주되지만 (변경 사항은 제공하지 않음) 문서가 가리키는 문서 매번 돌연변이가 일어날 수 있습니다. 따라서 실제로는 흐린 선이됩니다 (예에서는 배열을 변경할 수는 없지만 배열의 내용은 기억하십시오).

관련 문제