수업에서 개인 필드의 수정을 방지하려면 어떻게 해야 하는가?
내가 이런 수업을 한다고 생각해봐:
public class Test
{
private String[] arr = new String[]{"1","2"};
public String[] getArr()
{
return arr;
}
}
이제, 나는 위의 수업을 사용하는 다른 수업이 있다.
Test test = new Test();
test.getArr()[0] ="some value!"; //!!!
그래서 이것이 문제다.나는 밖에서 수업의 사적인 영역에 접속했다!어떻게 하면 이것을 막을 수 있을까?어떻게 하면 이 배열을 불변하게 할 수 있을까?이것은 모든 게터 방법을 동원해서 민간 분야에 접근하기 위해 노력해도 된다는 뜻인가? (과바 같은 도서관은 원하지 않는다.올바른 방법만 알면 된다.)
배열 대신 목록을 사용할 수 있는 경우 컬렉션은 수정할 수 없는 목록을 제공한다.
public List<String> getList() {
return Collections.unmodifiableList(list);
}
어레이의 복사본을 반환하십시오.
public String[] getArr() {
return arr == null ? null : Arrays.copyOf(arr, arr.length);
}
수식어private
다른 클래스에서 액세스되지 않도록 필드 자체만 보호하며, 이 필드에서 오브젝트 참조는 보호하지 않는다.참조된 개체를 보호해야 하는 경우 해당 개체를 제공하지 마십시오.변화하다
public String [] getArr ()
{
return arr;
}
다음으로:
public String [] getArr ()
{
return arr.clone ();
}
또는 ~로
public int getArrLength ()
{
return arr.length;
}
public String getArrElementAt (int index)
{
return arr [index];
}
그Collections.unmodifiableList
이미 언급된 바 있다-Arrays.asList()
이상하게도 아니야!나의 해결책은 또한 외부로부터의 목록을 사용하고 다음과 같이 어레이를 포장하는 것이 될 것이다.
String[] arr = new String[]{"1", "2"};
public List<String> getList() {
return Collections.unmodifiableList(Arrays.asList(arr));
}
배열을 복사할 때의 문제는 코드에 액세스할 때마다 배열이 크면 쓰레기 수거업자에게 확실히 많은 작업을 생성한다는 점이다.그래서 그 복사본은 간단하지만 정말 나쁜 접근법이다. "싸다"라고 말하고 싶지만, 기억력은 비싸다!특히 두 가지 이상의 요소가 있을 때는 더욱 그렇다.
의 소스 코드를 보면Arrays.asList
그리고Collections.unmodifiableList
사실 별로 만들어지지 않았다.첫 번째는 어레이를 복사하지 않고 랩으로 감싸기만 하고, 두 번째는 목록을 랩으로 감싸서 변경 사항을 사용할 수 없게 한다.
당신은 또한 표준보다 더 나은 것을 사용할 수 있다.unmodifiableList
이 수업은 구글에 의해 만들어진 Guava 라이브러리의 일부분이다.
다음 설명은 다음과 같다.
Collections.unmodifiedList(java.util)와 달리.목록)은 여전히 변경할 수 있는 별도의 컬렉션의 보기입니다. ImableList의 인스턴스는 자체적인 개인 데이터를 포함하며 절대 변경되지 않음
사용 방법의 간단한 예는 다음과 같다.
public class Test
{
private String[] arr = new String[]{"1","2"};
public ImmutableList<String> getArr()
{
return ImmutableList.copyOf(arr);
}
}
이러한 관점에서 시스템 어레이 복사본을 사용하십시오.
public String[] getArr() {
if (arr != null) {
String[] arrcpy = new String[arr.length];
System.arraycopy(arr, 0, arrcpy, 0, arr.length);
return arrcpy;
} else
return null;
}
}
데이터 사본을 반환할 수 있다.데이터 변경을 선택한 호출자는 복사본만 변경함
public class Test {
private static String[] arr = new String[] { "1", "2" };
public String[] getArr() {
String[] b = new String[arr.length];
System.arraycopy(arr, 0, b, 0, arr.length);
return b;
}
}
문제의 핵심은 당신이 돌연변이 물체에 포인터를 돌려준다는 것이다.웁스. 객체를 불변하게 렌더링하거나(수정 불가능한 목록 솔루션) 객체의 복사본을 반환하십시오.
일반적으로 물체의 미세성은 물체가 변이될 경우 물체가 변경되는 것을 보호하지 않는다.이 두 가지 문제는 "키스 사촌"이다.
수정할 수 없는 목록을 반환하는 것은 좋은 생각이다.그러나 getter 메서드에 대한 호출 중 수정할 수 없는 목록은 여전히 클래스 또는 클래스에서 파생된 클래스에 의해 변경될 수 있다.
대신, 당신은 그 목록을 수정해서는 안 된다는 것을 클래스를 확장하는 누구에게도 분명히 해야 한다.
예를 들어 다음과 같은 코드로 이어질 수 있다.
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Test {
public static final List<String> STRINGS =
Collections.unmodifiableList(
Arrays.asList("1", "2"));
public final List<String> getStrings() {
return STRINGS;
}
}
위의 예에서 나는 다음과 같이 말했다.STRINGS
현장 공개, 원칙적으로 당신은 메서드 콜을 제거할 수 있다, 그 값은 이미 알려져 있다.
또한 문자열을 에 할당할 수도 있다.private final List<String>
클래스 인스턴스(instance)를 구성하는 동안 수정할 수 없는 필드.(시뮬레이터의) 상수 또는 인스턴스화 인수를 사용하는 것은 클래스 설계에 따라 달라진다.
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Test {
private final List<String> strings;
public Test(final String ... strings) {
this.strings = Collections.unmodifiableList(Arrays
.asList(strings));
}
public final List<String> getStrings() {
return strings;
}
}
예, 어레이 복사본을 반환하십시오.
public String[] getArr()
{
return Arrays.copyOf(arr);
}
Java 9 이후, 고정적인 공장 방식에서 불변 리스트를 구성할 수도 있으며, 이 방법에서는 수입과 코드가 약간 줄어들게 된다.
을 별이에서 은 경우이다.getUsers()
대로가 .users
필드를 수정할 수 있음:
class Computer {
private String[] users = new String[] {"user1", "user2", "user3"};
public String[] getUsers;
String[] getUsers() {
return this.users;
}
}
Computer c = new Computer();
c.getUsers()[0] = "me";
for (String user: c.getUsers()) {
System.out.println(user);
}
출력:
me
user2
user3
불변 목록 사용:
import java.util.List;
class Computer {
private String[] users = new String[] {"user1", "user2", "user3"};
public List<String> getUsers;
List<String> getUsers() {
return List.of(this.users);
}
}
Computer c = new Computer();
c.getUsers().set(0, "me");
for (String user: c.getUsers()) {
System.out.println(user);
}
출력:
user1
user2
user3
'programing' 카테고리의 다른 글
현재 프로세스가 GDB에서 실행 중인지 탐지하는 방법 (0) | 2022.05.20 |
---|---|
객체 일련화란? (0) | 2022.05.20 |
Vue js 동적으로 구성 요소 가져오기 (0) | 2022.05.20 |
Vue v-on:click.native in JSX? (0) | 2022.05.20 |
SRC, OBJ, BIN 하위 디렉터리를 사용하여 C 프로젝트의 Makefile을 생성하는 방법은? (0) | 2022.05.20 |